我正在使用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的新手,所以任何信息都会有很大的帮助。 感谢
答案 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”运算符是否有效。