2014-01-12 27 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. 如何傳遞匿名類型(其加入()生成),以通用

    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

如何放置條件作爲Join一部分方法來源?

使用該方法,您的條件需要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