1

我正在尝试从MySQL客户端运行以下 Linq 查询

    query = query.Where(c => c.CustomerRoles
                              .Select(cr => cr.Id)
                              .Intersect(customerRoleIds)
                              .Any()
                       );

这段代码看起来不错,但给出了错误:

System.NotSupportedException: Specified method is not supported.at MySql.Data.Entity.SqlGenerator.Visit(DbIntersectExpression expression)

在我看来,这就像 .Intersect 的问题。谁能告诉我这个错误的原因以及如何解决它?

4

4 回答 4

3

我认为@GertArnold 的帖子是正确且最好的答案,但我想知道你为什么还没有得到NotSupportedException?所以问题不应该来自intersect可能。

从哪里来customerRoleIds?是IQueryable<T>吗?

打断查询,一步一步完成。

如果您在这行没有遇到异常:

var a = query.Select(c => new { 
        c, 
        CustomerRoleIDList = c.CustomerRoles.Select(cr => cr.Id).AsEnumerable()
    })
    .ToList();

var b = customerRoleIds.ToList();

您必须通过以下方式获得结果:

var b = query.Where(c => c.CustomerRoles.any(u => customerRoleIds.Contains(u.Id)))
    .ToList();

如果您通过上述查询得到异常,您可以尝试这个最终解决方案首先获取数据,但请注意,所有数据将首先在内存中获取:

var a = query.Select(c => new { 
        c, 
        CustomerRoleIDList = c.CustomerRoles.Select(cr => cr.Id).AsEnumerable() 
    })
    .ToList();

var b = a.Where(c => c.CustomerRoleIDList.any(u => customerRoleIds.Contains(u)))
    .Select(u => u.c)
    .ToList();
于 2014-05-04T17:30:33.430 回答
2

在 LINQ to SQL 后端使用IntersectorExcept可能总是很麻烦。使用 Sql Server,它们可能会产生可怕的 SQL 查询。

通常支持,Contains因为这很容易转换为 SQLIN语句。您的查询可以重写为

query = query.Where(c => c.CustomerRoles
                 .Any(cr => customerRoleIds.Contains(cr.Id)));

我认为它customerRoleIds不会包含很多项目(通常不会有数百个角色),否则您应该注意不要达到语句中允许的最大项目数IN

于 2014-04-29T13:22:16.990 回答
1

尝试在相交之前添加 toList(),这应该在本地枚举结果而不是在 MySql 上运行,你会得到性能打击的想法。

 query = query.Where(c => c.CustomerRoles.Select(cr => cr.Id)).ToList().Intersect(customerRoleIds);
于 2014-04-28T15:25:49.467 回答
1
query.Where(c => c.CustomerRoles
                 .Any(v=>customerRoleIds.Any(e=>e == v.Id))
     .Select(cr => cr.Id))
     .ToList();
于 2014-04-28T15:39:58.580 回答