拥有所有权的类型属性对于EF Core中的已修改实体不持久 [英] Owned type property not persisting for a modified entity in EF Core
问题描述
我正在尝试在EF Core中实现某些对我在EF 6中非常有效的功能.
I'm trying to achieve something in EF Core that worked very well for me in EF 6.
我正在将 List< T>
属性的内容序列化为DB中的Json字符串.< T>
几乎可以是任何东西,因为Json.Net负责序列化我们扔给它的任何东西.我的集合公开了一个 Json
字符串属性,并负责对自身进行序列化/反序列化.
I'm serializing the contents of a List<T>
property as a Json string in the DB. <T>
can be pretty much anything, since Json.Net takes care of serializing whatever we throw at it. My collection exposes a Json
string property and takes care of serializing/deserializing itself.
对于结构化的嵌套数据,这种方法既方便又有效,因为关系模型会带来不必要的开销和复杂性.
This approach is convenient and efficient for structured nested data where a relational model would bring needless overhead and complexity.
在EF 6中,我将执行以下操作:
In EF 6 I would do something like this:
[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类型提供具体的实现:
EF 6 doesn't support mapping generic types, so we'd provide a concrete implementation for each type of List we might want:
public class PhoneNumberCollection : SelfSerializingCollection<PhoneNumber> { }
然后像这样使用它:
public class Contact {
public PhoneNumberCollection PhoneNumbers { get; set; }
}
就是这样.现在,我正在尝试在EF Core 2.0中实现相同的目标.
And that was it. Now, I'm trying to achieve the same in EF Core 2.0.
这是我到目前为止所拥有的. SelfSerializingCollection< T>
类未更改.
Here's what I have so far. The SelfSerializingCollection<T>
class is unchanged.
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
列.读取和创建新条目很好用.
So far so good. EF Core maps the PhoneNumbers_Json
column in the DB. Reading and creating new entries works just fine.
但是,与EF 6不同,不对现有实体上的 PhoneNumbers
集合所做的任何更改都不会持久保存到数据库中.我正在使用 _context.Entry(contactModelFromRequestBody).State = EntityState.Modified;
在典型的PUT方法中进行更新-与以前相同.但是由于某种原因,EF Core并未将我的 Json
字符串属性持久保存到数据库中,以用于 Modified
实体.
But, unlike in EF 6, any changes to the PhoneNumbers
collection on an existing entity are not being persisted back to the database. I am updating in a typical PUT method with _context.Entry(contactModelFromRequestBody).State = EntityState.Modified;
- same as before. But for some reason, EF Core is not persisting my Json
string property back to the DB for a Modified
entity.
有什么想法吗?
推荐答案
EF Core将拥有的类型像没有自己的身份的实体类型一样对待,因此将指向拥有类型的属性视为导航属性.并且将父实体状态设置为 Modified
不会级联到导航属性.
EF Core treats owned types like entity types w/o own identity, hence properties that point to owned type are treated as navigation properties. And setting the parent entity state to Modified
does not cascade to navigation properties.
但是 DbContext
或 DbSet
的 Update
方法确实可以级联,所以代替了
However the Update
method of DbContext
or DbSet
does cascade, so instead of
_context.Entry(contactModelFromRequestBody).State = EntityState.Modified;
您应该使用
_context.Update(contactModelFromRequestBody);
这篇关于拥有所有权的类型属性对于EF Core中的已修改实体不持久的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!