【问题标题】:Linq Entity Framework generic filter methodLinq Entity Framework 通用过滤器方法
【发布时间】:2010-07-10 17:26:36
【问题描述】:

我有一些方法可以对来自我的实体的数据执行标准过滤器(使用 Entity Framework v4)。

示例 #1:

protected IQueryable<Database.Product> GetActiveProducts( ObjectSet<Database.Product> products ) {

    var allowedStates = new string[] { "Active" , "Pending" };

    return (
        from product in products
        where allowedStates.Contains( product.State )
            && product.Hidden == "No"
        select product
    );

}

示例 #2:

protected IQueryable<Database.Customer> GetActiveProducts( ObjectSet<Database.Customer> customers ) {

    var allowedStates = new string[] { "Active" , "Pending" };

    return (
        from customer in customers
        where allowedStates.Contains( customer.State )
            && customer.Hidden == "No"
        select customer
    );

}

如您所见,除了它们操作的实体类型之外,这些方法是相同的。我有超过 10 种这些类型的方法,一种用于我系统中的每种类型的实体。

我试图了解如何拥有 1 个可以传入任何实体类型的单一方法,并在存在 2 个字段/属性时让它执行 where 子句。

我没有在数据库中使用继承,所以就系统而言,每个实体类型都有“隐藏”和“状态”字段是巧合。

我的谷歌搜索告诉我它与使用 Expression.Call() 构建代码有关,但我现在头晕目眩!

【问题讨论】:

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


    【解决方案1】:

    我想说添加接口比弄乱表达式树 反射更简单。 EF 实体是部分类,因此您应该能够执行以下操作:

    更新为包含类约束(参见 Mark 的评论)

    public interface IHideable
    {
      string State { get; }
      string Hidden { get; }
    }
    
    ...
    
    namespace Database
    {
      public partial class Product : IHideable { }
      public partial class Customer : IHideable { }
    }
    
    ...
    
    protected IQueryable<T> GetActive<T>(ObjectSet<T> entities)
        where T : class, IHideable
    {
      var allowedStates = new string[] { "Active" , "Pending" };    
    
      return (    
        from obj in entities
        where allowedStates.Contains(obj.State)
            && obj.Hidden == "No"
        select obj
      );
    }  
    

    【讨论】:

    • 我也更喜欢这个解决方案。顺便说一句,您需要一个类约束,因为 ObjectSet 需要一个。 where T : class, IHideable
    • 很好,马克; +1。我实际上并没有编译它。更新了示例以包含 class 约束。
    • 感谢 Mark H 提到类约束
    【解决方案2】:

    我想用IQueryable&lt;T&gt; 作为泛型方法的输入参数类型做同样的事情。

    我得到“无法转换类型.... LINQ to Entities 仅支持转换实体数据模型原始类型”的运行时异常。

    一段时间后我意识到,我忘记为泛型参数添加类约束。但是IQueryable&lt;T&gt; 不需要有类约束,它仍然需要在运行时解析类型。

    如果没有这篇文章,我会花上几个小时。谢谢:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-16
      • 2022-01-14
      • 1970-01-01
      相关资源
      最近更新 更多