gpt4 book ai didi

c# - EF Core 子元素的列表和属性之间的相交返回 "ArgumentNullException"

转载 作者:行者123 更新时间:2023-12-04 07:36:54 25 4
gpt4 key购买 nike

我目前正在尝试将 ID 列表与我的数据库实体的子属性相交。

这样做的目的是查找所有列表 ID 与子实体“Location”中至少一个实体相匹配的所有“Form”记录。我相信 SQL 等效项将在连接表“Locations”上执行 IN。

相关元素的结构如下:(我故意省略了所有其他属性)。

public class Form
{

[Column("FormId"), DatabaseGenerated(DatabaseGeneratedOption.Identity), Key]
public Guid Id { get; set; }
public virtual ICollection<Location> Locations { get; set; }
}

public class Location
{
[Column("LocationId"), DatabaseGenerated(DatabaseGeneratedOption.Identity), Key]
public Guid Id { get; set; }
}

我正在尝试执行以下操作:

var locationIdsL = locationIds.Split(',').Select(Guid.Parse).ToList();

return baseQuery.Include(x => x.Locations).Where(x => x.Locations.Select(y => y.Id).Intersect(locationIdsL).Count() == locationIdsL.Count);

* 假设 locationIdsL 变量是有效的 Guid 列表。

上面的代码返回以下异常:

System.ArgumentNullException: Value cannot be null. (Parameter'parameter') atSystem.Linq.Expressions.Expression.Lambda(Expression body, Stringname, Boolean tailCall, IEnumerable`1 parameters) atSystem.Linq.Expressions.Expression.Lambda(Expression body,ParameterExpression[] parameters) atMicrosoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.ReducingExpressionVisitor.Visit(Expressionexpression) atSystem.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitorvisitor, IArgumentProvider nodes) atSystem.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpressionnode) atSystem.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitorvisitor) atSystem.Linq.Expressions.ExpressionVisitor.Visit(Expression node)

但是,如果我像这样手动使用集合:

List<Form> forms = new List<Form>();
foreach (var form in baseQuery.Include(x => x.Locations))
{
var locations = form.Locations;
if (locations.Select(x => x.Id).Intersect(locationIdsL).Count() == locationIdsL.Count)
{
forms.Add(form);
}
}

forms 集合获取我期望看到的项目,最值得注意的是,无一异常(exception)。

由于显而易见的原因,后者不是一个可接受的解决方案,因为它需要加载整个数据集。

我不确定这里缺少什么,因为 EFCore 应该能够翻译第一个查询。

老实说,我的方法可能完全错误,我的查询可能完全“反模式化”,我不确定;欢迎任何建议。

最佳答案

I am not sure what I am missing here as EFCore should be able to translate the first query

可能会,如果 locationIdsL变量保存数据库查询(非内存 IQueryable<T> 类型)。问题在于它保存内存中集合,并且到目前为止 LINQ to Entities 查询中唯一支持的内存中集合操作是 Contains关于“原始”值集合,直接转换为 SQL IN (val1, val2, ..., valN)构造。

幸运的是,这足以实现相关查询。因为setA和setB的交集只不过是setA中的元素包含在setB中。所以Contains基于Where可以使用运算符代替 Intersect ,然后简单地计算结果(或使用 Count 的谓词版本作为 Where(...).Count() 的快捷方式),例如替换

x.Locations.Select(y => y.Id).Intersect(locationIdsL).Count() == locationIdsL.Count

x.Locations.Count(y => locationIdsL.Contains(y.Id)) == locationIdsL.Count

关于c# - EF Core 子元素的列表和属性之间的相交返回 "ArgumentNullException",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67696620/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com