[英]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
不會級聯到導航屬性。
然而, DbContext
或DbSet
的Update
方法確實級聯,因此不是
_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.