【发布时间】:2017-09-05 20:21:39
【问题描述】:
我正在使用 LinqKit 的修改版本,以便将我的扩展程序放在一个地方。
因此,我在每个实体类中都有一个单独的部分来定义我的表达式,例如对于tblMain:
public partial class tblMain
{
public static Expression<Func<tblMain, bool>> IsVisible => (e) => e.MainStatus == "Visible";
}
在查询中我现在可以写这样的东西
var visibleEntries = dbContext
.tblMain
.AsExpandable()
.Where(m => tblMain.IsVisible.Invoke(m))
.ToList();
这将返回表 tblMain 的所有可见条目。
我想知道是否有任何方法可以不让这个静态属性。这将使我能够像IVisibilityEntity 一样使用Interfaces 来强制特定类型上的公共IsVisible 属性。
现在我已经结束了:
public Expression<Func<bool>> IsVisible2 => Expression.Lambda<Func<bool>>(Expression.Invoke(IsVisible, Expression.Variable(typeof(tblMain))));
但这给我抛出了一个异常
InvalidOperationException:从范围“”引用了“tblMain”类型的变量“m”,但未定义。
使用Expression.Constant(this, typeof(tblMain)) 作为第二个参数时相同。
我想要的是这样的查询
var visibleEntries = dbContext
.tblMain
.AsExpandable()
.Where(m => m.IsVisible.Invoke())
.ToList();
这似乎没有太大的变化。但我真的希望能够使用接口功能来描述我的底层数据库模型。
通过接口,它还允许检查,例如if(myEntity is IVisibilityEntity) 做特定的可见性。
如果可以,有什么想法以及如何实现?
编辑 1
截至第一条评论。我使用LinqKit 为子查询启用相同的逻辑:
var visibleEntries = dbContext
.tblMain
.AsExpandable()
.Where(m => tblMain.IsVisible.Invoke(m))
.Select(m => new
{
VisibleSubs = m.tblSub.Where(s => tblSub.IsVisible.Invoke(s)).Select(s => new
{
// ...
})
})
.ToList();
上面的查询将为我提供所有可见的主条目及其相关(以及可见的)子条目。但这只是简单地写m.tblSub.Where(tblSub.IsVisible) 是不可能的,如下所示
CS1929 'ICollection<tblSub>' does not contain a definition for 'Where' and the best extension method overload 'Queryable.Where<tblSub>(IQueryable<tblSub>, Expression<Func<tblSub, bool>>)' requires a receiver of type 'IQueryable<tblSub>'
【问题讨论】:
-
在你的第一个 sn-p 中你可以写
.Where(tblMain.IsVisible)然后你甚至根本不需要 LINQKit。 -
@Servy 我知道这种用法。请参阅我更新的问题 (
Edit 1)。此解决方案也不能解决接口问题,也不适合子查询。
标签: c# linq expression expression-trees linqkit