2012-06-14 55 views
1

我試圖爲實體框架實現動態投影,以便能夠指定要返回的屬性列表獲取值的字典作爲結果。EF動態投影(映射到屬性值對的字典)

 public static IQueryable<Dictionary<string, object>> ProjectionMap<TSource> 
     (IQueryable<TSource> sourceModel, IEnumerable<string> properties) 
    { 
     var itemParam = Expression.Parameter(typeof (TSource), "item"); 

     var addMethod = typeof (Dictionary<string, object>).GetMethod("Add"); 

     var elements = properties. 
      Select(
       property => 
       Expression.ElementInit(addMethod, Expression.Constant(property), 
             GetPropertyExpression<TSource>(itemParam, property))). 
      ToList(); 

     var newDictionaryExpression = 
      Expression.New(typeof (Dictionary<string, object>)); 

     var dictionaryInit = Expression.ListInit(newDictionaryExpression, elements); 

     var projection = Expression.Lambda<Func<TSource, Dictionary<string, object>>>(dictionaryInit, itemParam); 

     return sourceModel.Select(projection); 
    } 

    public static Expression GetPropertyExpression<T>(ParameterExpression parameter, string propertyName) 
    { 
     var properties = typeof (T).GetProperties(); 
     var property = properties.First(p => p.Name == propertyName); 
     return Expression.Property(parameter, property); 
    } 

在運行時,運行下面的代碼引發異常用一個單一的元素

var query = ProjectionMap(db.Posts, new[]{"Subject"}); 
      var result = query.ToList(); 

NotSupportedException異常 只列出初始化物品LINQ支持到實體。

任何想法如何解決代碼或建議如何正確實施它? 在此先感謝。

回答

0

我得到了同樣的錯誤,但也許出於不同的原因(我還沒有試過你的代碼)。 希望這有助於我在添加選擇之前添加了.ToList()。我選擇了一個Hashtable,並且我認爲問題在於sql不知道如何去做,儘管我習慣於看到不同的錯誤。 不管怎樣,也許嘗試

return sourceModel.ToList().Select(projection); 

爲sourceModel是你的IQueryable(起初我會建議在性能ToList(),但是這已經是IEnumerable的。