LINQ-to-SQL에서 대소 문자를 구분하지 않는 문자열 비교
ToUpper와 ToLower를 사용하여 대소 문자를 구분하지 않는 문자열 비교를 수행하는 것이 현명하지 않다는 것을 읽었지만 LINQ-to-SQL과 관련하여 대안이 없습니다. String.Compare의 ignoreCase 및 CompareOptions 인수는 LINQ-to-SQL에서 무시됩니다 (대소 문자를 구분하는 데이터베이스를 사용하는 경우 대소 문자를 구분하지 않는 비교를 요청하더라도 대소 문자를 구분합니다). ToLower 또는 ToUpper가 가장 적합한 옵션입니까? 하나는 다른 것보다 낫습니까? 어딘가 ToUpper가 더 낫다는 것을 읽었지만 여기에 적용되는지 모르겠습니다. (나는 많은 코드 검토를하고 있으며 모두가 ToLower를 사용하고 있습니다.)
Dim s = From row In context.Table Where String.Compare(row.Name, "test", StringComparison.InvariantCultureIgnoreCase) = 0
이것은 단순히 row.Name을 "test"와 비교하는 SQL 쿼리로 변환되며 대 / 소문자를 구분하는 데이터베이스에서 "Test"및 "TEST"를 반환하지 않습니다.
당신이 말했듯이, ToUpper와 ToLower 사이에는 중요한 차이점이 있으며 대소 문자를 구분하지 않는 동등성 검사를 수행하려고 할 때 단 하나만 정확합니다.
대소 문자를 구분하지 않는 동등성 검사를 수행하는 가장 좋은 방법 은 다음과 같습니다.
String.Equals(row.Name, "test", StringComparison.OrdinalIgnoreCase)
그러나이 경우에는 작동 하지 않습니다 ! 따라서 우리는 ToUpper
또는 로 붙어 있습니다 ToLower
.
보안 안전을 위해 서수 IgnoreCase를 참고하십시오 . 그러나 사용하는 대소 문자를 구분하여 정확히 검사하는 목적은 용도에 따라 다릅니다. 그러나 일반적으로 등식 검사에 대해 동일을 사용하고 정렬 할 때 비교를 사용한 다음 작업에 적합한 문자열 비교를 선택하십시오.
마이클 카플란 (Michael Kaplan) (이와 같은 문화 및 캐릭터 취급에 대한 인정 된 당국)은 ToUpper와 ToLower에 대한 관련 게시물을 보유하고 있습니다.
그는 "String.ToUpper – ToLower 대신 ToUpper를 사용하고 OS 케이싱 규칙을 선택하기 위해 InvariantCulture를 지정합니다 "라고 말합니다.
System.Data.Linq.SqlClient.SqlMethods.Like(row.Name, "test")
내 쿼리에 사용 했습니다.
대소 문자를 구분하지 않는 비교를 수행합니다.
나는 Lambda 식을 사용하여 이것을 시도했지만 효과가있었습니다.
List<MyList>.Any (x => (String.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase)) && (x.Type == qbType) );
LINQ-to-SQL에 대소 문자를 구분하지 않는 문자열을 전달하면 변경되지 않은 SQL로 전달되고 비교는 데이터베이스에서 수행됩니다. 데이터베이스에서 대소 문자를 구분하지 않는 문자열 비교를 수행하려면 비교를 수행하는 람다 식을 만들고 LINQ-to-SQL 공급자는 해당 식을 문자열이 그대로있는 SQL 쿼리로 변환합니다.
예를 들어이 LINQ 쿼리는 다음과 같습니다.
from user in Users
where user.Email == "foo@bar.com"
select user
LINQ-to-SQL 공급자가 다음 SQL로 변환합니다.
SELECT [t0].[Email]
FROM [User] AS [t0]
WHERE [t0].[Email] = @p0
-- note that "@p0" is defined as nvarchar(11)
-- and is passed my value of "foo@bar.com"
보시다시피, 문자열 매개 변수는 SQL에서 비교됩니다. 즉, 예상대로 작동해야합니다.
대 / 소문자를 구분하는 Linq-Sql 쿼리를 수행하려면 다음 중 하나를 사용하여 서버 데이터 형식을 지정하여 'string'필드를 대 / 소문자를 구분합니다.
varchar(4000) COLLATE SQL_Latin1_General_CP1_CS_AS
또는
nvarchar(Max) COLLATE SQL_Latin1_General_CP1_CS_AS
참고 : 위 데이터 정렬 유형에서 'CS'는 '대소 문자 구분'을 의미합니다.
Visual Studio DBML Designer를 사용하여 속성을 볼 때“서버 데이터 형식”필드에 입력 할 수 있습니다.
자세한 내용은 http://yourdotnetdesignteam.blogspot.com/2010/06/case-sensitive-linq-to-sql-queries.html을 참조하십시오.
where row.name.StartsWith(q, true, System.Globalization.CultureInfo.CurrentCulture)
다음 2 단계 접근 방식이 저에게 효과적입니다 (VS2010, ASP.NET MVC3, SQL Server 2008, Linq to SQL).
result = entRepos.FindAllEntities()
.Where(e => e.EntitySearchText.Contains(item));
if (caseSensitive)
{
result = result
.Where(e => e.EntitySearchText.IndexOf(item, System.StringComparison.CurrentCulture) >= 0);
}
때로는 데이터베이스에 저장된 값에 공백이 포함될 수 있으므로 실행이 실패 할 수 있습니다.
String.Equals(row.Name, "test", StringComparison.OrdinalIgnoreCase)
이 문제에 대한 해결책은 공간을 제거한 다음 케이스를 변환하고 다음과 같이 선택하는 것입니다.
return db.UsersTBs.Where(x => x.title.ToString().ToLower().Replace(" ",string.Empty).Equals(customname.ToLower())).FirstOrDefault();
이 경우 참고
customname 은 데이터베이스 값과 일치하는 값입니다.
사용자 TB 는 클래스입니다
제목 은 데이터베이스 열입니다
Remember that there is a difference between whether the query works and whether it works efficiently! A LINQ statement gets converted to T-SQL when the target of the statement is SQL Server, so you need to think about the T-SQL that would be produced.
Using String.Equals will most likely (I am guessing) bring back all of the rows from SQL Server and then do the comparison in .NET, because it is a .NET expression that cannot be translated into T-SQL.
In other words using an expression will increase your data access and remove your ability to make use of indexes. It will work on small tables and you won't notice the difference. On a large table it could perform very badly.
That's one of the problems that exists with LINQ; people no longer think about how the statements they write will be fulfilled.
In this case there isn't a way to do what you want without using an expression - not even in T-SQL. Therefore you may not be able to do this more efficiently. Even the T-SQL answer given above (using variables with collation) will most likely result in indexes being ignored, but if it is a big table then it is worth running the statement and looking at the execution plan to see if an index was used.
참고URL : https://stackoverflow.com/questions/841226/case-insensitive-string-compare-in-linq-to-sql
'IT' 카테고리의 다른 글
데이터 세트에 커스텀 객체를 저장하는 방법? (0) | 2020.06.29 |
---|---|
ggplot2 라인 플롯에 범례 추가 (0) | 2020.06.29 |
PostgreSQL- "IN"절의 최대 매개 변수 수? (0) | 2020.06.28 |
x에서 y로 공변량 배열을 변환하면 런타임 예외가 발생할 수 있습니다 (0) | 2020.06.28 |
UNIX 쉘 스크립트에서“#! / bin / sh”줄은 무엇을 의미합니까? (0) | 2020.06.28 |