如何重构LINQ查询以使用委托或表达式<;Func<;T、 bool>>;
本文关键字:lt gt 表达式 Func bool 重构 何重构 LINQ 查询 | 更新日期: 2023-09-27 18:21:27
此方法非常有效,只生成1个查询(使用.Includes()进行预加载)。然而,我想重构AbleToDelete代码,使其更加可重用。(使用EF4)
public override IEnumerable<AffectProjection> SelectAll(SearchAffects page)
{
IQueryable<Affect> query = BuildSearchQuery(page);
IEnumerable<AffectProjection> results = query.Select(entity => new AffectProjection()
{
AffectID = entity.AffectID,
AffectCode = entity.AffectCode,
AffectName = entity.AffectName,
AbleToDelete = !((entity.Foo1s.Any(pa => !pa.Inactive))
|| (entity.Foo2s.Any(ea => !ea.Inactive))
|| (entity.Foo3s.Any(sa => !sa.Inactive))
|| (entity.Foo4s.Any(spa => !spa.Inactive)))
}).ToArray();
return results;
}
我把代码移到了Expression Func结构中,但不知道如何替换设置AbleToDelete属性的代码。劝告
public Expression<Func<Affect, bool>> DelegateExpression = entity =>
!((entity.Foo1s.Any(pa => !pa.Inactive))
|| (entity.Foo2s.Any(ea => !ea.Inactive))
|| (entity.Foo3s.Any(sa => !sa.Inactive))
|| (entity.Foo4s.Any(spa => !spa.Inactive)));
最后但同样重要的是,此解决方案编译但在运行时失败,错误为:"NotSupportedException-LINQ to Entities中不支持LINQ表达式节点类型"Invoke"。"尝试使用不支持的委托:
public override IEnumerable<AffectProjection> SelectAll(SearchAffects page)
{
IQueryable<Affect> query = BuildSearchQuery(page);
//Create delegate instance and register method -- single statement
var deleteAbilityAllowed = new CanDelete(GetAbleToDelete);
IEnumerable<AffectProjection> results = query.Select(entity => new AffectProjection()
{
AffectID = entity.AffectID,
AffectCode = entity.AffectCode,
AffectName = entity.AffectName,
AbleToDelete = deleteAbilityAllowed(entity)
}).ToArray();
return results;
}
public delegate bool CanDelete(Affect entity);
public bool GetAbleToDelete(Affect entity)
{
return !((entity.Foo1s.Any(pa => !pa.Inactive))
|| (entity.Foo2s.Any(ea => !ea.Inactive))
|| (entity.Foo3s.Any(sa => !sa.Inactive))
|| (entity.Foo4s.Any(spa => !spa.Inactive)));
}
请提前告知并感谢!
LINQKit包含允许您执行此操作的方法。有了它,您就可以使用yout DelegateExpression
。为此,将AsExpandable()
添加到查询源,然后使用Invoke()
:调用表达式
var expression = DelegateExpression;
var results = query.AsExpandable().Select(entity => new AffectProjection()
{
AffectID = entity.AffectID,
AffectCode = entity.AffectCode,
AffectName = entity.AffectName,
AbleToDelete = expression.Invoke(entity)
}).ToArray();
不过要小心,似乎不能直接从字段中使用表达式,它必须来自局部变量。