简体   繁体   English

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

[英]Why does L2E choke when I try to use an interface in my Where clause?

I have a LINQ to Entities query (using EF 4) that has some pretty complicated set-based filtering going on. 我有一个LINQ to Entities查询(使用EF 4),正在进行一些非常复杂的基于集合的过滤。 The code compiles just fine, but when I try to run it, I get the following error: 该代码可以很好地编译,但是当我尝试运行它时,出现以下错误:

Unable to create a constant value of type 'ITextEntity'. 无法创建类型为“ ITextEntity”的常量值。 Only primitive types ('such as Int32, String, and Guid') are supported in this context. 在这种情况下,仅支持基本类型(例如Int32,String和Guid)。

Now for the code. 现在获取代码。 I have an interface that looks like this: 我有一个看起来像这样的界面:

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

The idea is that these "Text Entities" represent lookup tables storing properties of Product . 这个想法是,这些“文本实体”代表存储Product属性的查找表。 If Products have a color, all red Products will contain a Color entity with TextValue = "Red", and there will be a Color entity decorated with this interface: 如果Products具有颜色,则所有红色Products将包含一个TextValue =“ Red”的Color实体,并且将使用以下接口装饰一个Color实体:

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

ITextEntities may have 1:N or N:N relationships back to Product . ITextEntities可以返回到Product具有1:N或N:N关系。

I have a nested collection (actually a List<IEnumerable<ITextEntity>> ) which contains sets of different entities implementing the ITextEntity interface. 我有一个嵌套的集合(实际上是List<IEnumerable<ITextEntity>> ),其中包含实现ITextEntity接口的不同实体的ITextEntity I want to use these sets to filter a sequence of Product s in a semi-inclusive fashion. 我想使用这些集合以半包容的方式过滤Product的序列。 Here's the code: 这是代码:

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

//...snip...

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

So what I'm trying to do is this: 所以我想做的是这样的:

  1. I have a set, Products, that I want to filter. 我有一个要过滤的产品集。
  2. For each of several types that implement ITextEntity , there's a set S of entities of that type. 对于实现ITextEntity的几种类型的ITextEntity ,都有一组该类型的实体。
  3. Each object O has a set OP of products. 每个对象O具有一组产品OP。
  4. For each Product prod in Products, 对于产品中的每个产品产品,
    for each set S, 对于每个集合S,
    for at least one O in S, 在S中至少有一个O
    OP must contain prod. OP必须包含产品。 If not, remove prod from Products. 如果不是,请从产品中删除产品。

As you can see, this is pretty complicated. 如您所见,这非常复杂。

I have the feeling that this is caused by LINQ not being able to work with the ITextEntity type, rather than a problem with my set operations. 我感觉这是由于LINQ无法使用ITextEntity类型而不是我的设置操作有问题引起的。 However, the complexity of the above is making this difficult to work with, and difficult to find a non-LINQ alternative. 但是,上述方法的复杂性使其难以使用,并且很难找到非LINQ的替代方案。 It's going to get pretty ugly if I can't use LINQ. 如果我不能使用LINQ,它将变得非常难看。

I found an MSDN page and a Stack Overflow thread discussing similar exceptions, but neither was much help. 我发现一个MSDN页面和一个Stack Overflow线程讨论了类似的异常,但是两者都没有太大帮助。 Another SO thread aims a finger at my use of the Contains method, but because of the complexity here, I haven't had much luck trying to replace it with the BuildOrExpression method. 另一个SO线程将手指指向我对Contains方法的使用,但是由于这里的复杂性,我没有很多运气尝试用BuildOrExpression方法替换它。 I doubt BuildOrExpression will work anyway, since this is EF 4 and Contains is supposed to be supported. 我怀疑BuildOrExpression是否可以正常运行,因为这是EF 4,并且应该支持Contains

So I'm rather stuck here. 所以我宁愿停留在这里。 Can anyone advise? 有人可以建议吗?

EDIT : This question was answered in Aug 2010, but I've come back to clean up the title and description. 编辑 :这个问题在2010年8月得到了回答,但是我回来整理标题和描述。

You're implicitly casting to ITextEntity . 您将隐式转换为ITextEntity But ITextEntity is not part of your entity data model, so the EF doesn't know how to translate its members into SQL. 但是ITextEntity不是您实体数据模型的一部分,因此EF不知道如何将其成员转换为SQL。 Contains is supported, but only with primitive or entity types. 支持Contains ,但仅包含原始或实体类型。 Also, you use IEnumerable , which also prevents translation to SQL; 另外,您使用IEnumerable ,这也防止了转换为SQL; you need IQueryable to be convertable to SQL. 您需要将IQueryable转换为SQL。

So if you remove the interface reference and IEnumerable , you should be able to execute the query on the DB server. 因此,如果删除接口引用和IEnumerable ,则应该能够在数据库服务器上执行查询。 Otherwise you have to go into L2O (with, eg, AsEnumerable() ). 否则,您必须进入L2O(例如,使用AsEnumerable() )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM