EF核心:找不到实体类型的属性的支持字段,并且该属性没有getter



我在EF Core中得到以下错误:找不到实体类型为"Child"的属性"ParentId"的支持字段,并且该属性没有getter。

这是我对子实体的配置:

// create shadow property for Parent
builder.Property<int>("ParentId").IsRequired();
// make shadow property and foreign key the PK as well
// i know this may not make the most sense here 
// in this scenario but it's what I want to do.
builder.HasKey("ParentId");
// configure FK
builder.HasOne(o => o.Parent)
.WithOne()
.HasForeignKey<Child>("ParentId");

以及我的实体:

public class Parent
{
public int Id { get; set; }
}
public class Child 
{
public Parent Parent { get; private set; }
public void SetParent(Parent p) => Parent = p;
}

当我调用dbContext.Children.Contains(myChild(:时发生错误

var child = new Child();
child.Parent = new Parent();
dbContext.Children.Add(child);
dbContext.SaveChanges();
// works fine
Assert.True(dbContext.Children.Any());
// throws InvalidOperationException
Assert.True(dbContext.Children.Contains(myChild)):

如果我将阴影属性作为真实属性添加到模型中,如下所示:

public class Child 
{
public int ParentId { get; set;} 
public Parent Parent { get; private set; }
public void SetParent(Parent p) => Parent = p;
}

然后一切正常。但如果可能的话,我想保留它作为影子财产。

更新:

刚刚检查了3天前发布的EF Core 3.1.7,异常已经消失,这意味着它已经被报告/识别并修复。因此,您可以简单地升级到该版本。

原件:

shadow属性的配置很好。不幸的是,您遇到了一个EF Core 3.x错误。

为了将Contains方法转换为SQL,EF Core必须将其转换为PK相等比较,类似于(在伪代码中(

dbContext.Children.Any(c => PK(c) == PK(myChild))

这可以从异常堆栈跟踪中看出,并且当PK是影子属性时,显然无法做到这一点。

我已经检查了最新的EF 5预览,它似乎已经修复(问题已经消失(。因此,在发布之前,解决方法是用相应的显式PK比较替换隐式实体相等比较(例如Contains(entity)Equals(entity)== entity等(。

在这种情况下,代替

dbContext.Children.Contains(child)

你可以使用

dbContext.Children.Any(c => c.Parent.Id == child.Parent.Id)

(由于另一个v3.x缺陷,SQL翻译更差(

dbContext.Children.Any(c => EF.Property<int>(c, "ParentId") == child.Parent.Id)

(与v5.0中一样,正确的SQL翻译,但使用"魔术"字符串,并需要显式指定阴影属性名称和类型(

public class Child 
{
public int ParentId{get;set;}
public Parent Parent { get; private set; }
public void SetParent(Parent p) => Parent = p;
}

您应该定义您的外键变量,并记住私有集不会在数据库中创建关系

最新更新