簡體   English   中英

EF Core:找不到實體類型屬性的支持字段,並且該屬性沒有 getter

[英]EF Core: No backing field could be found for property of entity type and the property does not have a 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)):

如果我將陰影屬性作為真實屬性添加到 model 中,如下所示:

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,異常消失了,說明已經上報/識別並修復。 因此,您可以簡單地升級到該版本。

原來的:

陰影屬性的配置很好。 不幸的是,您遇到了 EF Core 3.x 錯誤之一。

為了將Contains方法轉換為 SQL,EF Core 必須將其轉換為 PK 相等比較,類似於(在偽代碼中)

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

從異常堆棧跟蹤中可以看出,當 PK 是影子屬性時顯然沒有這樣做。

我目前檢查了最新的 EF 5 預覽版,它似乎已修復(問題消失了)。 因此,在它發布之前,解決方法是將隱式實體相等比較(例如Contains(entity)Equals(entity)== entity等)替換為相應的顯式 PK 比較。

在這種情況下,而不是

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)

(正確的 SQL 翻譯與 v5.0 相同,但使用“魔術”字符串並需要明確指定影子屬性名稱和類型)

public class Child 
{
    public int ParentId{get;set;}
    public Parent Parent { get; private set; }

    public void SetParent(Parent p) => Parent = p;
}

你應該定義你的外鍵變量並記住私有集不會在數據庫中創建關系

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM