1

我正在使用 的修改版本,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

我想知道是否有任何方法可以不拥有这个静态属性。这将使我能够使用Interfaceslike在特定类型上IVisibilityEntity强制使用公共属性。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>'
4

1 回答 1

0

像这样定义你的属性怎么样:https ://damieng.com/blog/2009/06/24/client-side-properties-and-any-remote-linq-provider 它本质上是以下形式的属性定义:

partial class Employee {
    private static readonly CompiledExpression<Employee,string> fullNameExpression
     = DefaultTranslationOf<Employee>.Property(e => e.FullName).Is(e => e.Forename + " " + e.Surname);
    private static readonly CompiledExpression<Employee,int> ageExpression
     = DefaultTranslationOf<Employee>.Property(e => e.Age).Is(e => DateTime.Now.Year - e.BirthDate.Value.Year - (((DateTime.Now.Month < e.BirthDate.Value.Month) || (DateTime.Now.Month == e.BirthDate.Value.Month && DateTime.Now.Day < e.BirthDate.Value.Day)) ? 1 : 0)));

  public string FullName {
    get { return fullNameExpression.Evaluate(this); }
  }

  public int Age {
    get { return ageExpression.Evaluate(this); }
  }
}

并使用 Microsoft.Linq.Translations 包来解决。

于 2017-04-12T21:56:09.557 回答