我目前工作的一个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