用于泛型类型的.NET LINQ to Entities基where子句

本文关键字:Entities where 子句 to LINQ 泛型类型 NET 用于 | 更新日期: 2023-09-27 18:21:15

我正在使用实体框架访问我的域模型,所有这些模型都实现了一个接口(IPublishable),该接口指定了指示项是否已发布的属性。

当从前端访问项目时,我总是想过滤掉未发布的项目。因此,每次编写查询时,我都会执行类似的操作(其中以下DbSets Objects1和Objects2都实现IPublishable

context.Objects1.Where( x => x.IsPublished ...).OrderBy( x => x.Id).ToList()
context.Objects2.Where( x => x.IsPublished ...).First()

理想的情况是,如果我可以在我的web应用程序中的所有查询中注入通用的Where()子句,或者如果有一种方法可以编写一个扩展方法,我可以在每个查询中包含该方法。

我尝试为所有linq查询创建扩展方法

public static IEnumerable<T> FrontEnd<T>(this DbSet<T> dbSet) where T : class {
  return dbSet.Cast<IPublishable>().Where( x => x.IsPublished ...).Cast<T>();
}

像这样使用。。。

context.Objects1.FrontEnd().Where( x => ...).OrderBy(...

然而,我得到了错误"LINQ to Entities只支持铸造EDM基元或枚举类型"

我是英孚的新手,所以任何信息都会有很大帮助。感谢

用于泛型类型的.NET LINQ to Entities基where子句

根据评论更新-这适用于

public static IQueryable<T> FrontEnd<T>(this DbSet<T> dbSet)
    where T : class, IPublishable
{
    return dbSet.Where(x => x.IsPublished);
}

并且可以这样使用:

context.Objects1.FrontEnd().Where( x => ...).OrderBy(...

您可以尝试以下任一选项:

public static IQueryable<dynamic> FrontEnd(this DbSet<dynamic> dbSet)
{
    return dbSet.Where(x => (x as IPublishable).IsPublished);
}

public static IQueryable<T> FrontEnd<T>(this DbSet<T> dbSet)
    where T : class, IPublishable
{
    return dbSet.Where(x => x.IsPublished);
}

注:

第一个选项使用动态,因此速度较慢对于第二个选项,您必须在对FrontEnd()的调用中指定类型例如

context.Objects1.FrontEnd<Objects1>().Where( x => ...).OrderBy(...

我认为LINQ to Entities不知道如何将强制转换运算符与SQL请求相匹配。作为一个建议,你可以试试这样的东西:

IEnumerable<IPublishable> ReadPublishable(Expression<Func<DomainModelType, bool>> condition)

该表达式充当谓词。因此,您将一个谓词传递给ReadPublishable函数,该谓词用于筛选所需的IPublishable对象。我成功地尝试了,但只是在简单的谓词上,所以,如果使用"is"或"as"运算符,我不知道这是否有效。