此方法效果很好,只生成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)));
}
请提前告知并谢谢你!
答案 0 :(得分:2)
LINQKit包含允许您执行此操作的方法。有了它,您可以使用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();
但要小心,似乎你不能直接从字段中使用表达式,它必须来自局部变量。