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

时间:2013-07-05 13:30:40

标签: c# .net linq entity-framework linq-to-entities

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

从前端访问项目时,我总是希望过滤掉未发布的项目。所以,每次我写一个查询时,我都在做类似的事情(下面的DbSets Objects1和Objects2都实现了IPublishable

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

如果我可以在我的网络应用程序中的所有查询中注入公共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原语或枚举类型”

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

2 个答案:

答案 0 :(得分:2)

根据评论更新 - 这有效

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()调用中指定类型 e.g。

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

答案 1 :(得分:0)

我认为LINQ to Entities不知道如何将强制转换操作符与SQL请求进行匹配。作为建议,您可以尝试类似的东西:

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

表达式充当谓词。因此,您向ReadPublishable函数传递一个谓词,该谓词可过滤您需要的IPublishable对象。我尝试成功,但只是在简单的谓词上,所以,我不知道如果你使用“是”或“as”运算符是否有效。