我正在尝试从MySQL
客户端
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的一个问题。谁能告诉我这个错误的原因以及如何解决它?
答案 0 :(得分: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();
答案 1 :(得分:2)
使用Intersect
或Except
可能总是很麻烦LINQ到SQL后端。使用Sql Server,它们可能会产生可怕的SQL查询。
通常支持Contains
,因为它很容易转换为SQL IN
语句。您的查询可以重写为
query = query.Where(c => c.CustomerRoles
.Any(cr => customerRoleIds.Contains(cr.Id)));
我不认为customerRoleIds
会包含很多项目(通常不会有数百个角色),否则你应该注意不要点击maximum number of items allowed in an IN
statement。< / p>
答案 2 :(得分:1)
尝试在交叉之前添加toList(),这应该在本地枚举结果而不是在MySql上运行,你会受到性能影响。
query = query.Where(c => c.CustomerRoles.Select(cr => cr.Id)).ToList().Intersect(customerRoleIds);
答案 3 :(得分:1)
query.Where(c => c.CustomerRoles
.Any(v=>customerRoleIds.Any(e=>e == v.Id))
.Select(cr => cr.Id))
.ToList();