我目前工作的一個EF
網站,我有這樣的數據庫對象:如何構建這個複雜的Expression Func?
public partial class Association
{
public Association()
{
this.Users = new HashSet<User>();
}
public Guid Id { get; set; }
public Guid ItemId { get; set; }
[ForeignKey("ItemId")]
public virtual Item Item { get; set; }
[InverseProperty("Association")]
public virtual ICollection<User> Users { get; set; }
}
項目類:
public partial class Item
{
public Item()
{
this.Associations = new HashSet<Association>();
}
public Guid Id { get; set; }
public ItemTypeEnum Type { get; set; }
[InverseProperty("Item")]
public virtual ICollection<Association> Associations { get; set; }
}
而該詞典:
public static Dictionary<ItemTypeEnum, int> MaxOccupationRange = new Dictionary<ItemTypeEnum, int>()
{
{ ItemTypeEnum.Type1, 1 },
{ ItemTypeEnum.Type2, 2 },
{ ItemTypeEnum.Type3, 5 },
{ ItemTypeEnum.Type4, 10 },
};
我需要Expression<Func<Association, bool>>
如果association.Users.Count < MaxOccupationRange[association.Item.Type]
將返回true
,否則返回false
。
我認爲這應該大致看起來像下面的方法,但不幸的是,我不熟悉Expression
概念來實現這種事情。
當調試以下結果時,它似乎計算(未優化但是)正確的表達式。
public static Expression<Func<TSource, bool>> MyExprMethod<TSource, TKey, TKey2, TValue>(Expression<Func<TSource, TKey>> source, Expression<Func<TSource, TKey2>> source2, IReadOnlyDictionary<TKey, TValue> dict)
{
var body = dict
.Aggregate((Expression)null, (next, dicEntry) => next == null
? Expression.Condition
(
Expression.LessThan(source2.Body, Expression.Constant(dicEntry.Value)),
Expression.Constant(true),
Expression.Constant(false)
)
: Expression.Condition
(
Expression.Equal(source.Body, Expression.Constant(dicEntry.Key)),
Expression.Condition
(
Expression.LessThan(source2.Body, Expression.Constant(dicEntry.Value)),
Expression.Constant(true),
next
),
next
)
);
return Expression.Lambda<Func<TSource, bool>>(body, source.Parameters[0]);
}
我嘗試調用這種方式:
var expr = MyHelper.MyExprMethod((Association x) => x.Item.Type, (Association b) => b.Users.Count, Item.MaxOccupationRange);
但很明顯,它抱怨的b
參數是未分配的,因爲它不會在結果拉姆達出現。
我嘗試了很多事情(匿名類型而不是兩個來源等),但似乎我對這個概念太不熟悉,我找不到一種方法來生成這樣的表達式。
有人請告訴我嗎?
非常感謝。
編輯
這裏的呼叫內容:
var filter = PredicateUtils.True<Association>();
var expr = MyHelper.MyExprMethod((Association x) => x.Item.Type, (Association b) => b.Users.Count, Item.MaxOccupationRange);
filter = filter.And(expr);
var associations = entities.Associations.Where(filter);
return associations .OrderBy(a => a.Id).ToPagedList(pageNb, 2);
而這裏的消息,在最後一行(ToPagedList)所示:The parameter 'b' was not bound in the specified LINQ to Entities query expression
哪裏不抱怨關於B?上面的代碼編譯並運行,*除*'EF'外。 – 2017-02-04 13:59:31
感謝您的回答,我編輯了第一篇文章,希望這可以幫助 –
您希望'協會x'和'協會b'成爲* same *參數:看看我的答案,我正在展示如何做到這一點。 – 2017-02-04 15:34:06