3

我使用EF代碼優先4.2, 當where子句需要動態構建時,你提出了什麼樣的解決方案? 然而,包括功能將是非常必需的:建立動態where子句,Linq到SQL

var results = db.Set<dynamicType>.Where("dynamic conditions").Include("...."); 

上面的動態條件需要查找到另一個表篩選記錄: 如果我想寫在LINQ表達式它會是這樣的:

var result = db.Set<Contact>().Where(c=>c.AccountId == _Id_param || db.Set<LinkTable>().Any(a=>a.FkFieldId == c.AccountId && a.ParentId == _Id_param)).Include("Quotes"); 

我基本上需要上述表達式的動態LINQ,因爲對於不同類型的Where子句字段的變化(Contact只是一個例子),例如在一個模型中FK字段可能是「AccountId」而在另一個模型中它需要爲「AccountFKId」。所以Where子句必須是動態的!

回答

1

UPDATE

我能夠直接修改表達式樹來解決這個問題。

使用從TomasP's blog一個想法,幫助了很多:

的關鍵是建立了內部查詢第二的IQueryable,然後把它作爲對現有動態模型的IQueryable的表達的表達。

IQueryable<LinkTable> linkQuery = db.Set<LinkTable>().AsQueryable(); 

MethodCallExpression internalQueryWhere = Expression.Call(typeof(Queryable), "Where", new Type[] { linkQuery.ElementType }, linkQuery.Expression,Expression.Lambda<Func<LinkTable, bool>>(myfilters, new ParameterExpression[] { filterParameter })); 

linkQuery = linkQuery.Provider.CreateQuery<LinkTable>(internalQueryWhere); 

Expression anyMethodExpr = Expression.Call(typeof(Queryable), "Any", new Type[] { linkQuery.ElementType }, linkQuery.Expression); 

現在您可以將anyMethodExpr傳遞給原始實體的IQueryable where子句。

3

IQueryable是組合的,因此您可以即時構建查詢:

var query = db.Set<Contact>().Include(...); 

if (something) 
{ 
    query = query.Where(...); 
} 

// Other wheres 

的Linq是強類型的,所以你總是至少要知道你要在你的Set<>調用start什麼類型。你可以使它通用但不是動態的(除非你要通過反思來寫它)。

您可以使用dynamic linq來定義帶字符串的條件,但至少需要知道Set<>的類型。

+0

感謝您的回覆,我如何在動態LINQ中編寫此查詢?我覺得我不知道Dynamic linq能夠把它放在一起。特別是我需要從where子句中的另一個表中查找的部分。 – sam360 2011-12-16 23:38:11