2014-10-06 52 views
0

雖然功能強大,但System.Linq.Dynamic庫缺少文檔,特別是在更復雜的查詢必須遵循哪些約定時。如何在動態Linq表達式中使用帶有Func參數的linq擴展?

在我正在處理的查詢中,它包含一個FirstOrDefault調用,但我似乎無法使其正常工作。

這裏是整個(unworking)表達:

"Locations.FirstOrDefault(x => x.IsPrimaryLocation).Address1 as Address" 

我可以這樣寫FirstOrDefault表達與動態LINQ工作?

寫這個表達式的正確方法是什麼?

+0

無關,與動態LINQ,但'FirstOrDefault()'可以返回當您嘗試訪問'Address1'(或)財產將拋出一個異常的'null'值。 – DavidG 2014-10-06 14:23:00

+0

是的,儘管我的特定問題在它達到該點之前就已經出現,因爲它無法正確解析字符串。我會接受一個只用First()而不是FirstOrDefault()來解決這個問題的答案。 – 2014-10-06 14:26:24

+0

這可能有助於http://stackoverflow.com/questions/4849973/use-of-single-in-dynamic-linq – DavidG 2014-10-06 14:30:05

回答

1

擴展動態庫肯定是一個選項,正如已經提出的那樣。 替代給出的Where動態LINQ的使用動態對象的上下文或存儲庫「位置」返回一個IQueryable

public static class DynamicQueryable { 

    public static IQueryable<T> Where<T>(this IQueryable<T> source, string predicate, params object[] values) { return (IQueryable<T>) Where((IQueryable) source, predicate, values); } 

    public static IQueryable Where(this IQueryable source, string predicate, params object[] values)  { 


然後使用where可能包含動態字符串謂詞並跟隨firstOrDefault。其中,如果需要的話

DynamicLocations.Where("IsPrimaryLocation",new string[]).FirstOrDefault().Address1 as Address; 

詳細
(捕獲或測試空不予考慮)

DynamicLocations.Where(x => x.IsPrimaryLocation).FirstOrDefault().Address1 as Address; 

或動態: 您可以在方法揭露在其上實例化作爲一種​​通用的存儲庫類動態的

 public virtual IQueryable<TPoco> DynamicWhere(string predicate, params object[] values) { 
     return AllQ().Where(predicate, values); 
    } 

動態通用存儲器Ÿ實例樣品

public class RepositoryFactory<TPoco> where TPoco : BaseObject,new() { 

    public IRepositoryBase<TPoco> GetRepository(DbContext context) { 

     // get the Pocotype for generic repository instantiation 
     var pocoTypes = new[] {typeof (TPoco)}; // but supports <T,U> 
     Type repBaseType = typeof (RepositoryBase<>); 

     IRepositoryBase<TPoco> repository = InstantiateRepository(context, repBaseType, pocoTypes); 

     return repository; 
    } 


    private IRepositoryBase<TPoco> InstantiateRepository(DbContext context, Type repType, params Type[] args) { 

     Type repGenericType = repType.MakeGenericType(args); 
     object repInstance = Activator.CreateInstance(repGenericType, context); 
     return (IRepositoryBase<TPoco>)repInstance; 
    } 

}