2009-02-20 2 views
11

내가 다양한 WhereWhereBetween 문을 사용하여 특정 집합으로 컬렉션을 좁히는 쿼리 가능 문이 있습니다. 지금 Where || WhereBetween의 종류를 추가해야합니다. 다른 말로하면, 나는 지금까지 가지고있는 것처럼 그것들을 하나로 묶을 수 없다. 왜냐하면 그것이 And로 작용할 것이기 때문이다. 그래서, 어떻게해야합니까?C#, Linq2Sql : 두 쿼리를 하나로 연결할 수 있습니까?

  1. WhereBetween을 사용하여 두 queryables 내가 가지고있는 것과, 하나 Where를 사용하고, 하나를 만듭니다

    나는 두 가지 가능성을 참조하십시오. 그런 다음을 연결하십시오. 이것이 가능한지 모르겠습니까? 또한, 비록 내 특정 경우에는 아니지만, 당신은 가장 가능성이 중복으로 끝날 것입니다 ...

  2. 어떻게 든 WhereWhere 식과 표현은 WhereBetween에서 생성 된 일종의 Or와 병합합니다.

제 1, 언급 한 바와 같이, 나는 확실히 처음 아니라고도 할 수 있습니다. 그리고 만약 그렇다면, 나는 그것을 할 수있는 좋은 방법이라고 확신하지 못합니다.

둘째로, 나는 옵션으로 볼 수 있지만 모든 세부 사항에 대해서는 완전히 확신 할 수 없습니다. 아래는 내가 지금 사용하는 내 다른 질문에서 WhereBetween 방법이며 위대한 작품 : 나는 어쩌면 새로운 방법으로의 발현 건물 부분을 추출 할 수 있다고 생각하고

public static IQueryable<TSource> WhereBetween<TSource, TValue>(
     this IQueryable<TSource> source, 
     Expression<Func<TSource, TValue>> selector, 
     IEnumerable<Range<TValue>> ranges) 
    { 
     var param = Expression.Parameter(typeof(TSource), "x"); 
     var member = Expression.Invoke(selector, param); 
     Expression body = null; 
     foreach (var range in ranges) 
     { 
      var filter = Expression.AndAlso(
       Expression.GreaterThanOrEqual(member, 
        Expression.Constant(range.A, typeof(TValue))), 
       Expression.LessThanOrEqual(member, 
        Expression.Constant(range.B, typeof(TValue)))); 
      body = body == null ? filter : Expression.OrElse(body, filter); 
     } 
     return body == null ? source : source.Where(
      Expression.Lambda<Func<TSource, bool>>(body, param)); 
    } 

. 아마도 다음과 같습니다.

public static IQueryable<TSource> WhereBetween<TSource, TValue>(
     this IQueryable<TSource> source, 
     Expression<Func<TSource, TValue>> selector, 
     IEnumerable<Range<TValue>> ranges) 
    { 
     return source.Where(WhereBetween(selector, ranges)); 
    } 

    public static Expression<Func<TSource, bool>> WhereBetween<TSource, TValue>(
     Expression<Func<TSource, TValue>> selector, 
     IEnumerable<Range<TValue>> ranges) 
    { 
     var param = Expression.Parameter(typeof(TSource), "x"); 
     var member = Expression.Invoke(selector, param); 
     Expression body = null; 
     foreach (var range in ranges) 
     { 
      var filter = Expression.AndAlso(
       Expression.GreaterThanOrEqual(member, 
        Expression.Constant(range.A, typeof(TValue))), 
       Expression.LessThanOrEqual(member, 
        Expression.Constant(range.B, typeof(TValue)))); 
      body = body == null ? filter : Expression.OrElse(body, filter); 
     } 
     return body == null 
      ? ø => true 
      : Expression.Lambda<Func<TSource, bool>>(body, param); 
    } 

다음 새 메서드를 사용하여 쿼리 가능 식 대신 표현식을 가져올 수 있습니다. 예를 들어 WhereBetween(ø => ø.Id, someRange)이고 예를 들어 ø => ø.SomeValue == null이라고 가정 해 보겠습니다. 그 둘을 Or와 어떻게 결합시킬 수 있습니까? 나는 을 WhereBetween 방법에 사용하고 있는데, 내가 필요한 것일 수도 있고 아니면 Expression.Or 일 수도있다. 하지만 나는이 표현에 대해 매우 불안정합니다. 따라서 무엇을 선택할 것인지, 아니면 올바른 방향으로 가고 있는지 확실하지 않습니다. p

누군가가 나에게 몇 가지 조언을 줄 수 있습니까?

답변

9

여기에는 두 가지 옵션, 즉 Queryable.Union 또는 표현식 조합이 있습니다. 나는 OrElse를 통해, 일반적으로 거라고 후자의 선호 - 어떤 (LINQ는 - 투 - SQL 이상으로) 당신은 2 식 (아래 참조)로 할 수있는 -하지만 어떤 경우에이 구성을하셔야합니다 :

using(var ctx = new DataClasses1DataContext()) 
    { 
     ctx.Log = Console.Out; 
     Expression<Func<Customer, bool>> lhs = 
      x => x.Country == "UK"; 
     Expression<Func<Customer, bool>> rhs = 
      x => x.ContactName.StartsWith("A"); 

     var arr1 = ctx.Customers.Where(
      lhs.OrElse(rhs)).ToArray(); 

     var arr2 = ctx.Customers.Where(lhs) 
      .Union(ctx.Customers.Where(rhs)).ToArray(); 
    } 

모두를 arr1arr2은 각각 하나의 데이터베이스 적중 만 수행합니다 (TSQL은 다르지만 첫 번째는 절에 OR이고 두 번째 쿼리에는 UNION이라는 두 개의 별도 쿼리가 있음).

여기 내가 사용하는 확장 메서드는 다음과 같습니다

static Expression<Func<T, bool>> OrElse<T>(
    this Expression<Func<T, bool>> lhs, 
    Expression<Func<T, bool>> rhs) 
{ 
    var row = Expression.Parameter(typeof(T), "row"); 
    var body = Expression.OrElse(
     Expression.Invoke(lhs, row), 
     Expression.Invoke(rhs, row)); 
    return Expression.Lambda<Func<T, bool>>(body, row); 
} 
+0

는 그 행 것은 무엇이든 잘 될 수 있을까?(모든 문자열은 물론) – Svish

+0

SQL 성능 등을 생각하면'WHERE' 절에있는'UNION' 또는'OR'을 사용하면 더 효율적입니까? – Svish

+0

아주 좋습니다. 이 질문은 (변형 된 형태로) 계속 나오고 OrElse는 그 (것)들을 전부 해결하는 마술 총알일지도 모르다. –

관련 문제