이어서 LINQ 동적 조합 조회PredicateExtensions 설명
먼저 코드를 붙여서 분석하기: 코드
- public static class PredicateExtensions
- {
- public static Expression<Func<T, bool>> True<T>() { return f => true; }
-
- public static Expression<Func<T, bool>> False<T>() { return f => false; }
-
- public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expression1,
- Expression<Func<T, bool>> expression2)
- {
- var invokedExpression = Expression.Invoke(expression2, expression1.Parameters
- .Cast<Expression>());
-
- return Expression.Lambda<Func<T, bool>>(Expression.Or(expression1.Body, invokedExpression),
- expression1.Parameters);
- }
-
- public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1,
- Expression<Func<T, bool>> expression2)
- {
- var invokedExpression = Expression.Invoke(expression2, expression1.Parameters
- .Cast<Expression>());
-
- return Expression.Lambda<Func<T, bool>>(Expression.And(expression1.Body,
- invokedExpression), expression1.Parameters);
- }
- }
그중에 네 가지 방법만 있는데 트루,false,Or,And이다. 딱 보면 여기가 논리 연산에 대한 조작이라는 것을 알 수 있다.그 중에서True,False는 표현식을 초기화하는 것입니다. 이 종류를 보지 못하기 전에 저는 null을 사용합니다. null을 사용합니다. 이것은 And,Or 논리 조작이 없을 때 null 판단을 하고,null을 사용하면 다음 표현식을 되돌려줍니다.여기에 트루가 생겼다. 팩스는 표현식을 초기화한 셈이어서 더 이상 귀찮게 할 필요가 없다.
True,False의 초기화에는 우리의 정상적인 표현식에 영향을 주지 않는 규칙이 있다.우리가 언어를 처음 배웠을 때 논리와 가짜는 가짜이고 논리나 진실은 진실이다. 그러면 이 문장은 우리의 이 두 표현식의 초기화에 활용될 수 있다.우리가 True,false에서 표현식과 연결된 표현식의 논리를 And로 연산할 때 우리는 True를 사용해야 한다. 그러면 이 논리 조건의 진위는 우리의 뒤에 있는 표현식(논리와 가짜는 가짜이고 진실은 확실하지 않다)에 달려 있다. 우리의 정상적인 표현식에 영향을 주지 않았는가?같은 논리로 Or로 연산할 때는 False를 사용해야 한다. (논리나 진실이 진실이고 가짜가 확실하지 않으면 다른 표현식에 달려 있다.)아주 간단하지, 아니면 그 말인지, 나 같은 쥐새끼들은 응시 교육이 우리의 사고를 속박하고 있다는 것을 생각하기 어려울 것이다.
And, Or 이것은 표현식 논리 연산 연결이고 그 주체는 왼쪽 표현식 body Invoke를 꺼내서 오른쪽 표현식 연결과 되돌려줍니다.
내 결론을 검증하기 위해 우리는 몇 가지 작은 테스트를 했다. (여기는 컨트롤러 프로그램으로 바꾸기 편리하도록)
테스트 1: True and 연결,코드
- public static void Test1()
- {
- DbDataContext db = new DbDataContext();
- Expression<Func<TemplateDocument, bool>> expressleft =
- PredicateExtensions.True<TemplateDocument>();
- expressleft = expressleft.And(t => t.CategoriesID > 3);
-
- Expression<Func<TemplateDocument, bool>> expressright =
- PredicateExtensions.True<TemplateDocument>();
- expressright = expressright.And(t => t.CategoriesID < 5);
-
- expressleft= expressleft.Or(expressright);
- var sql = db.GetCommand(db.TemplateDocument.Where(expressleft).Select(t => new {
- t.TemplateID, t.TemplateName, t.CategoriesID })).CommandText;
- Console.WriteLine(sql);
-
- }
출력 sql:
SELECT [t0].[TemplateID], [t0].[TemplateName], [t0].[CategoriesID] FROM [dbo].[TemplateDocument] AS [t0] WHERE ([t0].[CategoriesID] > @p0) OR ([t0].[CategoriesID] < @p1
Linq 표현식이 없어서 True 조건을 스마트하게 제거했습니다. (True & & XX1)| (True & & XX2) = XX1 | XX2.위에서 설명한 바와 같이 첫 번째 조건을 False의 Or 연결로 변경해도 마찬가지일 것입니다. 테스트를 해 봅시다.
테스트 2 코드
- public static void Test2()
- {
- DbDataContext db = new DbDataContext();
- Expression<Func<TemplateDocument, bool>> expressleft =
- PredicateExtensions.False<TemplateDocument>();// True False
- expressleft = expressleft.Or(t => t.CategoriesID > 3);// And Or
-
- Expression<Func<TemplateDocument, bool>> expressright =
- PredicateExtensions.False<TemplateDocument>();
- // True False
- expressright = expressright.Or(t => t.CategoriesID < 5);
- // And Or
- expressleft = expressleft.Or(expressright);
- var sql = db.GetCommand(db.TemplateDocument.Where(expressleft).Select(t => new {
- t.TemplateID, t.TemplateName, t.CategoriesID })).CommandText;
- Console.WriteLine(sql);
-
- }
출력 sql
SELECT
[
t0
]
.
[
TemplateID
]
,
[
t0
]
.
[
TemplateName
]
,
[
t0
]
.
[
CategoriesID
]
FROM
[
dbo
]
.
[
TemplateDocument
]
AS
[
t0
]
WHERE
(
[
t0
]
.
[
CategoriesID
]
>
@p0
)
OR
(
[
t0
]
.
[
CategoriesID
]
<
@p1
)
이전 예에서 sql을 출력한 것과 같습니다. (False||||XX1)||(False||XX2) = XX1|||X2.True 또는 Or 접속 방식을 변경하면 어떨까요?
테스트 3: 코드
- public static void Test3()
- {
- DbDataContext db = new DbDataContext();
- Expression<Func<TemplateDocument, bool>> expressleft =
- PredicateExtensions.True<TemplateDocument>();
- expressleft = expressleft.Or(t => t.CategoriesID > 3);
-
- Expression<Func<TemplateDocument, bool>> expressright =
- PredicateExtensions.False<TemplateDocument>();
- expressright = expressright.Or(t => t.CategoriesID < 5);
-
- expressleft = expressleft.And(expressright);
- var sql = db.GetCommand(db.TemplateDocument.Where(expressleft).Select(t => new {
- t.TemplateID, t.TemplateName, t.CategoriesID })).CommandText;
- Console.WriteLine(sql);
-
- }
출력 sql:
SELECT
[
t0
]
.
[
TemplateID
]
,
[
t0
]
.
[
TemplateName
]
,
[
t0
]
.
[
CategoriesID
]
FROM
[
dbo
]
.
[
TemplateDocument
]
AS
[
t0
]
WHERE
[
t0
]
.
[
CategoriesID
]
<
@p0
응, 표현식이 하나밖에 없어. 당연하지. 너의 첫 번째 표현식은 (True|||||XX1) & & (False||XX2) = True & & XX2=XX2.이 테스트를 해서 나는 마이크로소프트가 코드에서 이렇게 스마트하게 판단할 수 있다는 것에 정말 탄복했다.차라리 조건을 완전히 없애고 우리는 중간의 And를 Or:(True|||XX1)||(False|||XX2)=True||||X2=True로 변경합니다.이거는 혼자.
테스트해 봤는데 where 조건이 보이지 않을 거예요.쇼쿤은 Linq 동적 조회와 모호한 조회 (원본 예시 포함) 에서 결과를 요약했다.
1: 구조 함수가 True를 사용하는 경우: 단일 AND는 유효하고 다중 AND는 유효합니다.단일 OR은 유효하지 않으며 여러 OR는 유효하지 않습니다.혼합 시 AND 뒤에 쓰인 OR 유효 2: 구조 함수가false를 사용할 때: 단일 AND는 무효이고 여러 AND는 무효입니다.한 개의 OR는 유효하고 여러 개의 OR는 유효하다.섞을 때 OR 뒤에 쓴 AND가 유효합니다.
검증:
1 구조 함수가 True를 사용하는 경우:
(1): 한 AND가 유효하고 여러 AND가 유효하다. 물론True&&XX=XX
(2): 단일 OR은 유효하지 않으며, 다중 OR은 유효하지 않습니다. True | | XX=True는 유효하지 않습니다.
(3): 혼합 시 AND에 적힌 OR은 유효합니다. (True & XX)||| XXX1 = XX| XXX1 유효합니다. (True | | XXX) & & XXX1 = True & & & XXXX1 = 쇼보 선배가 말한 것은 유효하지 않습니다. (우리가 필요로 하는 표현식에 비해 유효하지 않지만 사실은 유효합니다) (True | | | XX) | XXX = True | | XXX1 = True(여기는 where 조건이 보이지 않습니다).
2: False를 사용하는 구조 함수:
트루와 마찬가지로 나는 유도하지 않고 게으름을 피웠다.
이상은 모두 개인의 의견입니다. 만약 무슨 잘못이 있으면 지도하고 정정해 주십시오.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[파이썬 기초] 파이썬의 특수한 방법을 이해하고 코드를 읽어주세요!이번에는 파이톤의'특별한 방법'에 대한 해설을 진행한다. 나는 파이톤의 실제 업무에서 다른 사람이 쓴 코드를 자주 읽는다. 익숙하지 않으면 무엇을 하고 있는지 모르지만 시간만 지나갈 수 있다. 이런 상황을 방지하기 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.