zoukankan      html  css  js  c++  java
  • EF6学习笔记十九:不一样的复杂类型

    要专业系统地学习EF推荐《你必须掌握的Entity Framework 6.x与Core 2.0》。这本书作者(汪鹏,Jeffcky)的博客:https://www.cnblogs.com/CreateMyself/

    先来说一下二进制类型,我也就不实践了,直接记录一下书上说的一段话

    EF支持二进制属性来存储二进制文件,比如在博客中存储一张图片

    public byte[] BannerImage{get;set;}
    View Code

    如果我们想更改这张图片,那么必须通过设置一个新的byte[]实例来实现。不要尝试去改变已经存在二进制数组的内容。因为DetectChanges不会进入二进制数组里面来看其内容是否已经发生了改变。

    换言之,将纸巾纸数组当做是不变的,只有重新设置新的二进制数组,实例才能进行数据更新。

    现在来看一下复杂类型。

    我们添加一个Person.里面有个复杂类型叫Address,那么如果没有Address,我们也必须要赋值一个空的对象

    //  添加的时候,如果复杂类型没值,那么一定要给一个空值
    ctx.People.Add(new Person { Name = "dfd" });
    ctx.SaveChanges();
    View Code

     不然报错

    System.Data.Entity.Infrastructure.DbUpdateException: Null value for non-nullable member. Member: 'Address'. ---> System.Data.Entity.Core.UpdateException: Null value for non-nullable member. Member: 'Address'.
    在 System.Data.Entity.Core.Mapping.Update.Internal.ExtractorMetadata.RetrieveMember(IEntityStateEntry stateEntry, IExtendedDataRecord record, Boolean useCurrentValues, EntityKey key, Int32 ordinal, ModifiedPropertiesBehavior modifiedPropertiesBehavior)

    需要这样

    //  添加成功
    ctx.People.Add(new Person { Name = "李四", Address = new Address() });
    ctx.SaveChanges();
    View Code

    那么修改了,正常的修改是OK 的

    //  可以修改成功
    var first = ctx.People.First();
    first.Address.Province = "aaa";
    first.Address.City = "ss";
    first.Address.Area = "ff";
    ctx.SaveChanges();
    View Code

    但是结合昨天认识到的DetectChanges,那么关闭DetectChangs来修改

    //  关闭自动追踪,以属性赋值的方式来修改复杂属性
    //  不报错,但是修改不成功,
    ctx.Configuration.AutoDetectChangesEnabled = false;
    var first = ctx.People.FirstOrDefault();
    first.Address.Province = "ddd";
    first.Address.City = "dfd";
    first.Address.Area = "ere";
    ctx.SaveChanges();
    View Code

    不报错,也不会修改成功。这个还是比较致命的吧,报个错始终是好的吧

    行,看看API的方式修改

     //  用API修改,可以修改
     try
     {
         ctx.Configuration.AutoDetectChangesEnabled = false;
         var first = ctx.People.FirstOrDefault();
         //Console.WriteLine(JsonConvert.SerializeObject(first));
         var complex = ctx.Entry(first).ComplexProperty(x => x.Address);
         complex.Property(x => x.Province).CurrentValue = "湖南";
         complex.Property(x => x.City).CurrentValue = "岳阳";
         complex.Property(x => x.Area).CurrentValue = "回复";
         ctx.SaveChanges();
     }
     finally
     {
         ctx.Configuration.AutoDetectChangesEnabled = true;
     }
    View Code

    没有问题

    那么,书上说,在关闭自动追踪后,可以采用给整个复杂类型赋值一个新的实例的方式来修改

    但是我跟着做没有成功,还是得通过API的方式来

    //  关闭自动追踪,不修改复杂类型中的属性值,而是设置一个新的复杂类型实例
    try
    {
        ctx.Configuration.AutoDetectChangesEnabled = false;
        var p = ctx.People.FirstOrDefault();
        //  书上说这样可以,但是还是不行啊
        //p.Address = new Address { Province = "广西", City = "钦州", Area = "df" };
        //  下面这个可以
        ctx.Entry(p).ComplexProperty(x => x.Address).CurrentValue = new Address { Province = "广西", City = "钦州", Area = "fff" };
        ctx.SaveChanges();
    }
    finally
    {
        ctx.Configuration.AutoDetectChangesEnabled = true;
    }
    View Code

    那么我们要知道一点,EF不会为复杂类型创建变更追踪代理。如果你用代理追踪的方式来,是修改不成功的。

  • 相关阅读:
    python爬取斗图网中的 “最新套图”和“最新表情”
    SpringBoot (1) idea下的环境搭建及demo
    python爬取视频网站m3u8视频,下载.ts后缀文件,合并成整视频
    微信小程序—day05
    从零起步做到Linux运维经理, 你必须管好的23个细节
    前后端分离原理
    图文并茂|为你揭开微服务架构的“神秘面纱”!
    swarm集群日常部分操作
    OpenStack 部署运维实战
    京东618:Docker扛大旗,弹性伸缩成重点 (2015-06-23)
  • 原文地址:https://www.cnblogs.com/jinshan-go/p/10313121.html
Copyright © 2011-2022 走看看