2014-01-12 2 views
3

내가 두 개의 테이블이있는 데이터베이스가 있습니다건물 Linq는 일반적인 쿼리

public class A { 
    public string Name { get; set; } 
    public int Id { get; set; } 
} 

public class B { 
    public int Id { get; set; } 
    public bool Prop1 { get; set; } 
    public bool Prop2 { get; set; } 
    public bool Prop3 { get; set; } 
    public bool Prop4 { get; set; } 
} 

public class DataContext : DbContext { 
    DbSet<A> Table1 { get; set: } 
    DbSet<B> Table2 { get; set; } 
} 

내가 매개 변수 "Prop1"로 걸릴 것 기능을 쓰고 싶어를, "Prop2", ..., "PropX" 및 Table1에서 적절한 행을 리턴하십시오. 이 같은 뭔가 :

public List<A> GetByProp(string prop) { 
    var result = new List<A>(); 

    using (var db = new DataContext()) { 
     result = db.Table1.Join(db.Table2, t1=>t1.Id, t2=>t2.Id, (t1,t2)=>new {t1,t2}). 
          Where(????????). //t=>t.t2.prop == true 
          Select(t=>t.t2); 

    } 
    return result; 
} 

이 할 수있는 적절한 방법은 무엇입니까?

... 나는 식 트리를 사용하려고했지만, 나는 그들의 stucked있어

  1. 어떻게 두 개의 점으로 표현을 구축

    ? (t.t2.prop == true)가

  2. 어떻게 Join의 일부로서 조건을 배치에 대한 일반적인

    var p = Expression.Parameter(typeof(???), t2); //??? - anonymous class 
    var t = Expression.Constant(true, typeof(bool)); 
    var e = Expression.Equal(p, t); 
    var l = Expression.Lambda<Func<???, bool>>(e, p); 
    
+1

[This (http://stackoverflow.com/questions/307512/how-do-i-apply-orderby-on-an-iqueryable-using-a-string-column-name-within-a-gene)는'OrderBy'에 대한 것이지만 출발점이 될 수 있습니다. –

+0

문자열로 속성 매개 변수가 필요합니까? 대신식이 될 수 있습니까? – Magnus

+0

표현이 가능합니다. – Michael

답변

2

방법에 ((참여하는)를 생성) 익명 형식을 전달할 수 있습니다 방법 소스?

위의 방법을 사용하면 상태가 Expression<Func<B, true>>이고 표현식 트리를 사용하여 쉽게 만들 수 있습니다.

List<T> result; 

var param = Expression.Parameter(typeof(B), "x"); 
var trueExp = Expression.Constant(true); 
var condition = Expression.Equal(Expression.Property(param, prop), trueExp); 
var whereLambda = Expression.Lambda<Func<B, bool>>(condition, param); 

using (var db = new DataContext()) 
{ 
    result = db.Table1 
       .Join(db.Table2.Where(whereLambda), 
        t1 => t1.Id, 
        t2 => t2.Id, 
        (t1, t2) => new { t1, t2 }) 
       .Select(t => t.t1) 
       .ToList(); 
} 
return result; 

업데이트

당신이 컴파일러가 익명 ​​형식 추론해야한다 초기 설계를 따르십시오 :

public static Expression<Func<T, bool>> GetPropertyCondition<T>(T source, string prop) 
{ 
    var param = Expression.Parameter(typeof(T), "x"); 
    var trueExp = Expression.Constant(true); 
    var condition = Expression.Equal(
         Expression.Property(
          Expression.Property(param, "t2"), prop), 
          trueExp); 
    var whereLambda = Expression.Lambda<Func<T, bool>>(condition, param); 
    return whereLambda; 
} 

을 당신이 그런 식으로 호출 할 수 있습니다 :

var result = new List<A>(); 

var anonymous = new { t1 = (A)null, t2 = (B)null }; 
var condition = GetPropertyCondition(anonymous, prop); 

using (var db = new DataContext()) 
{ 
    result = db.Table1.AsQueryable() 
       .Join(db.Table2.AsQueryable(), t1 => t1.Id, t2 => t2.Id, (t1, t2) => new { t1, t2 }) 
       .Where(condition) 
       .Select(t => t.t1) 
       .ToList(); 
} 
return result; 

은 동일한 기본 익명 클래스를 공유하는 어셈블리 내에서 동일한 속성 집합 (속성 이름과 속성 형식이 모두 일치해야 함)이있는 모든 익명 형식의 개체를 공유한다는 사실을 사용합니다. 따라서 typeof(anonymous)Join 확장 메소드에 의해 반환 된 유형과 일치합니다.

+0

감사합니다. 나는 직장에서 이것을 내일 시도 할 것이다)) – Michael