首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >EF核中修改的实体不持久化的拥有类型属性

EF核中修改的实体不持久化的拥有类型属性
EN

Stack Overflow用户
提问于 2017-10-22 09:18:18
回答 2查看 2.6K关注 0票数 7

我正试图在EF核心中实现一些对我在EF 6中非常有用的东西。

我正在将List<T>属性的内容序列化为DB中的Json字符串。<T>几乎可以是任何东西,因为Json.Net负责序列化我们抛给它的任何东西。我的集合公开了一个Json字符串属性,并负责序列化/反序列化自身。

这种方法对于结构化嵌套数据来说是方便和有效的,因为关系模型会带来不必要的开销和复杂性。

在EF 6中,我会这样做:

代码语言:javascript
复制
[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不支持映射泛型类型,因此我们将为我们可能需要的每种类型的列表提供一个具体的实现:

代码语言:javascript
复制
public class PhoneNumberCollection : SelfSerializingCollection<PhoneNumber> { }

然后像这样使用它:

代码语言:javascript
复制
public class Contact {
    public PhoneNumberCollection PhoneNumbers { get; set; }
}

就是这样。现在,我正试图在EF Core 2.0中实现同样的目标。

到目前为止我的情况是这样的。SelfSerializingCollection<T>类不变。

代码语言:javascript
复制
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映射DB中的PhoneNumbers_Json列。读取和创建新条目工作得很好。

但是,与EF 6不同,对现有实体上的PhoneNumbers集合的任何更改都是而不是被持久化回数据库。我正在用_context.Entry(contactModelFromRequestBody).State = EntityState.Modified;更新一个典型的PUT方法-和以前一样。但出于某种原因,EF没有将我的Json字符串属性持久化回Modified实体的DB。

有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-22 10:03:08

EF Core处理拥有的类型,如实体类型w/o自己的标识,因此指向所属类型的属性被视为导航属性。并且将父实体状态设置为Modified不会级联到导航属性。

然而,Update方法的DbContextDbSet确实是级联的,所以

代码语言:javascript
复制
_context.Entry(contactModelFromRequestBody).State = EntityState.Modified;

你应该使用

代码语言:javascript
复制
_context.Update(contactModelFromRequestBody);
票数 13
EN

Stack Overflow用户

发布于 2017-10-22 09:58:19

似乎有必要手动为我自己的类型设置修改后的实体状态:

代码语言:javascript
复制
_context.Entry(contact).Reference(p => p.PhoneNumbers)
    .TargetEntry.State = EntityState.Modified;

虽然我仍然希望找到一个更通用的解决方案,不需要我在每次更新时标记所有拥有的属性,但这确实很有效。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46872428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档