实体框架中的通用查询方法

时间:2011-12-16 09:38:19

标签: c# entity-framework generics entity-framework-4

在我的数据库中,我有一个具有属性int DeleteState的表。我想要一个通用的方法来查询这些表。换句话说,执行此操作的方法:Context.Table.Where(x => x.DeleteState == 0)

我以为我可以这样做:

public static class Extensions
{
  public static IQueryable<T> Exists<T>(this IQueryable<T> qry) where T : IDeletable
  {
    return qry.Where(x => x.DeleteState == 0);
  }
}

IDeletable是这样的:

public interface IDeletable
{
    int DeleteState { get; set; }
}

现在我只需要在EF模型中添加IDeletable

public partial class Table : EntityObject, IDeletable { ... }

我用模板机制做到了这一点。

不幸的是,它不起作用:(它编译很好,但在运行时抛出:

Unable to cast the type 'Table' to type 'IDeletable'. LINQ to Entities only supports casting Entity Data Model primitive types

如果我这样称呼它:

Context.Table.Exists();

我该如何解决这个问题?你能想到修复或不同的方法来实现类似的结果吗? THX

4 个答案:

答案 0 :(得分:0)

您遇到的问题是实体框架只能使用表达式树。您的函数直接执行查询,而不是构建表达式树。

更简单的解决方案是添加Model Defined Function

可以直接在上下文的实例上调用模型定义的函数。

答案 1 :(得分:0)

在实际查询之前,您是否尝试将对象转换为IDeletable? e.g。

public static IQueryable<T> Exists<T>(this IQueryable<T> qry)
{     
    return qry.Select<T, IDeletable>(x => x).Where(x => x.DeleteState == 0).Cast<T>();
}

我没有测试过这段代码,但错误响了,我记得我必须做类似的事情。

答案 2 :(得分:0)

也许:

public static IQueryable<T> Exists<T>(this IQueryable<T> qry)
{
    return qry.Where(x => (!typeof(IDeletable).IsAssignableFrom(x.GetType()) || typeof(IDeletable).IsAssignableFrom(x.GetType()) && ((IDeletable)x).DeleteState == 0));
}

答案 3 :(得分:0)

Tsss,这就是答案:Linq Entity Framework generic filter method

我忘了这里的class

  

...其中T:,IDeletable