拥有所有权的类型属性对于EF Core中的已修改实体不持久 [英] Owned type property not persisting for a modified entity in EF Core

查看:43
本文介绍了拥有所有权的类型属性对于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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆