簡體   English   中英

EF Core中已修改實體的擁有類型屬性不存在

[英]Owned type property not persisting for a modified entity in EF Core

我正在嘗試在EF Core中實現一些在EF 6中非常適合我的東西。

我將List<T>屬性的內容序列化為DB中的Json字符串。 <T>可以是幾乎任何東西,因為Json.Net負責序列化我們拋出的任何東西。 我的集合公開了一個Json字符串屬性,並負責序列化/反序列化。

這種方法對於結構化嵌套數據來說是方便有效的,其中關系模型會帶來不必要的開銷和復雜性。

在EF 6中我會做這樣的事情:

[ComplexType]
public class SelfSerializingCollection<T> : Collection<T>
{
    public void AddRange(IEnumerable<T> collection)
    {
        foreach (var item in collection)
        {
            Add(item);
        }
    }

    protected string Json
    {
        get { return JsonConvert.SerializeObject(this); }
        private set
        {
            Clear();

            if (value == null)
            {
                return;
            }

            AddRange(JsonConvert.DeserializeObject<T[]>(value));
        }
    }
}

EF 6不支持映射泛型類型,因此我們為每種類型的List提供了我們可能需要的具體實現:

public class PhoneNumberCollection : SelfSerializingCollection<PhoneNumber> { }

然后像這樣使用它:

public class Contact {
    public PhoneNumberCollection PhoneNumbers { get; set; }
}

就是這樣。 現在,我正試圖在EF Core 2.0中實現相同的目標。

這是我到目前為止所擁有的。 SelfSerializingCollection<T>類未更改。

public class Contact {
    // EF Core supports generic types so we don't need a concrete implementation
    // for each collection type.
    public SelfSerializingCollection<PhoneNumber> PhoneNumbers { get; set; }
}

public class MyDbContext : DbContext
{
    // ...

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // EF Core does not support the [ComplexType] attribute
        // but we now have .OwnsOne() in EF Core 2
        modelBuilder.Entity<Contact>().OwnsOne(p => p.PhoneNumbers);
    }
}

到現在為止還挺好。 EF Core映射數據庫中的PhoneNumbers_Json列。 閱讀和創建新條目工作得很好。

但是,與EF 6不同,現有實體上對PhoneNumbers集合的任何更改都不會持久保存回數據庫。 我正在使用_context.Entry(contactModelFromRequestBody).State = EntityState.Modified;更新典型的PUT方法_context.Entry(contactModelFromRequestBody).State = EntityState.Modified; - 和之前一樣。 但由於某種原因,EF Core不會將我的Json字符串屬性保留回Modified實體的DB。

有任何想法嗎?

EF Core將擁有的類型視為沒有自己身份的實體類型,因此指向擁有類型的屬性被視為導航屬性。 將父實體狀態設置為Modified不會級聯到導航屬性。

然而, DbContextDbSetUpdate方法確實級聯,因此不是

_context.Entry(contactModelFromRequestBody).State = EntityState.Modified;

你應該使用

_context.Update(contactModelFromRequestBody);

似乎有必要為我擁有的類型手動設置修改后的實體狀態:

_context.Entry(contact).Reference(p => p.PhoneNumbers)
    .TargetEntry.State = EntityState.Modified;

雖然我仍然希望找到一個更通用的解決方案,但不要求我在每次更新時都標記所有擁有的屬性。

暫無
暫無

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

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