当我尝试在Where子句中使用接口时,为什么L2E会阻塞?

时间:2010-08-19 15:03:15

标签: c# linq entity-framework entity-framework-4 set-theory

我有一个LINQ to Entities查询(使用EF 4),它有一些非常复杂的基于集合的过滤。代码编译得很好,但是当我尝试运行它时,我收到以下错误:

  

无法创建“ITextEntity”类型的常量值。在此上下文中仅支持原始类型(例如Int32,String和Guid')。

现在代码。我有一个看起来像这样的界面:

public interface ITextEntity
{
    int ID { get; set; }
    string TextValue { get; set; }
    EntityCollection<Product> Products { get; set; }
}

这个想法是这些“文本实体”代表存储Product属性的查找表。如果Products有颜色,则所有红色产品都将包含TextValue =“Red”的Color实体,并且将有一个使用此界面修饰的Color实体:

public partial class Color : ITextEntity 
{ 
    //ID, TextValue, and Products implemented in EF-generated code
}

ITextEntities可能会将1:N或N:N关系返回Product

我有一个嵌套集合(实际上是List<IEnumerable<ITextEntity>>),它包含一组实现ITextEntity接口的不同实体。我想使用这些集合以半包容的方式过滤Product的序列。这是代码:

List<IEnumerable<ITextEntity>> InclusiveFilters;
IQueryable<Product> Products;

//...snip...

Products = Products.Where(prod => 
    InclusiveFilters.All(filter => 
        filter.Any(iTextEnt => 
            iTextEnt.Product.Contains(prod)
        )
    )
);

所以我要做的就是:

  
      
  1. 我有一套产品,我想过滤。
  2.   
  3. 对于实现ITextEntity的几种类型中的每一种,都有一种   设置该类型的实体S.
  4.   
  5. 每个对象O都有一套O.P的产品。
  6.   
  7. 对于产品中的每个产品,
            对于每组S,
                对于S中至少有一个O,
                    O.P必须包含prod。如果没有,请从产品中删除产品。
  8.   

如您所见,这非常复杂。

我觉得这是由LINQ无法使用ITextEntity类型引起的,而不是我的set操作有问题。然而,上述的复杂性使得难以使用,并且很难找到非LINQ替代方案。如果我不能使用LINQ,那将会非常难看。

我发现an MSDN pageStack Overflow thread讨论了类似的例外情况,但两者都没有太多帮助。 Another SO thread旨在指导我使用Contains方法,但由于此处的复杂性,我尝试用BuildOrExpression方法替换它并没有太多运气。我怀疑BuildOrExpression无论如何都会起作用,因为这是EF 4并且应该支持Contains

所以我宁愿被困在这里。有人可以建议吗?

编辑:这个问题已于2010年8月得到解答,但我已回来清理标题和说明。

1 个答案:

答案 0 :(得分:1)

您隐式转向ITextEntity。但ITextEntity不是您的实体数据模型的一部分,因此EF不知道如何将其成员转换为SQL。支持Contains,但仅支持原始类型或实体类型。此外,您使用IEnumerable,这也会阻止转换为SQL;您需要IQueryable才能转换为SQL。

因此,如果删除接口引用和IEnumerable,则应该能够在DB服务器上执行查询。否则你必须进入L2O(例如AsEnumerable())。