有一个列表,policiesToDelete
实体类,MonitoringRelations
。从这个列表中,我选择了两个元素并解释了一个新的列表:
var policyKeysToDelete = policiesToDelete
.Select(r => new {r.PolicyId, r.GroupId})
.ToList();
现在,我有一个查询,我想在其中比较列表中的元素policyKeysToDelete
。
var objectsToDelete = (from p in storageContext.MonitoringRelations
where policyKeysToDelete
.Any(x => x == new {p.PolicyId, p.GroupId})
select p)
.ToList();
问题:上面的查询抛出此异常:
NotSupportedException: Unable to create a constant value of type 'Anonymous type'. Only primitive types or enumeration types are supported in this context.
我尝试将匿名列表更改为list<tuple<PolicyId, GroupId>>
,但这也没有帮助,抛出了几乎相同的异常。我尝试使用Contains
代替Any
但这也没有帮助。
知道我该如何解决这个问题吗?
无法将复杂对象的列表转换为 SQL 查询。EF 可以执行的操作是在将简单值列表与 .Contains
方法一起使用时将其转换为 SQL。
因此,如果从policyKeysToDelete
中提取 PolicyId 列表和组 ID 列表,并使用它来使用 EF 尽可能多地进行选择,则可以使用 Linq-to-对象在结果集中执行完整检查,然后在内存中
警告:您从数据库中提取了太多内容,因此根据数据量,不同的解决方案可能会更好。
var policyKeysToDelete = policiesToDelete
.Select(r => new {r.PolicyId, r.GroupId})
.ToList();
// List of values types, which can be translated to SQL
var policyIds = policyKeysToDelete.Select(x => x.PolicyId).ToList();
var groupIds = policyKeysToDelete.Select(x => x.GroupId).ToList();
var objectsToDelete = storageContext.MonitoringRelations
// Do the part that we can do in the database, which is select the records
// which have an corresponding PolicyId or GroupId
.Where(x => policyIds.Contains(x.PolicyId) || groupIds.Contains(x.GroupId))
// Use this method to indicate that whatever follows after should not be
// translated to SQL
.AsEnumerable()
// Do the full check in-memory
.Where(x => policyKeysToDelete
.Any(y => x.PolicyId == y.PolicyId && x.GroupId == y.GroupId)
)
.ToList();