zoukankan      html  css  js  c++  java
  • Entity Framework 4.1/4.3 之六 (DBContext 之 3 状态跟踪 ) jerry

     

    Entity Framework 4.1/4.3 之六 (DBContext  之 3 状态跟踪)

     

      咱们接着来讲DBContext,这回内容将与DBContext 2中所讲的内容连贯起来。

     

      二、DBContext对于实体的增、删、改  (Adding, Changing, and Deleting Entities)

          DBContext 2中我们讲到了“增、删、改”,其中已经讲了“增、删、改”。还有部分内容没讲,我们补全。

           

          (1)、查找增加模式 (The “Find or Add” Pattern)

            场景:我们常常会增加一条记录,增加的步骤是先查找有没有相同记录存在,如果不存在内里将新记录新增到数据库中。在老版EF中我们会执行两次操作:即先找,在增。这无形中要与数据库交互两。

            DBContext为我们提供了新的解决方案,即Find or Add,我们来看看代码:

        private static void FindOrAddPerson()
        {
          using (var context = new BreakAwayContext())
          {
            var ssn = 123456789;
            var person = context.People.Find(ssn)?? context.People.Add(new Person
            {
              SocialSecurityNumber = ssn,
              FirstName = "jerry",
              LastName = "tom"
            });
            Console.WriteLine(person.FirstName);
          }
        }

        代码看起来非常的直观,如果Find(ssn)在缓存或者数据库中找到了该记录,则输出,否则则新增一条记录。

     

            (2)、新增关系数据(Adding a Relationship Between Objects)

            说实话,这个理解起来有点绕,不好解释。我们还是直接来看下面的代码吧!

        private static void NewGrandCanyonResort()
        {
          using (var context = new BreakAwayContext())
          {
            var resort = new Resort
            {
              Name = "Pete's Luxury Resort"
            };
            context.Lodgings.Add(resort);
            var canyon = (from d in context.Destinations
                    where d.Name == "Grand Canyon"
                    select d).Single();
            canyon.Lodgings.Add(resort);
            context.SaveChanges();
          }
        }

        Destinations 与 Lodgings 是一对多的关系,首先我们创建一个 resort 对象,将它加入到 Lodgings 集合中。然后我们找到父集合Destinations ,将resort 对象加入到Destinations包含的Lodgings集合中,然后SaveChanges,这种关联关系就建立起来了,相应的数据也保存到了数据库中。就是这么个意思,通俗的讲,就是先在从表里增加一条记录,然后将新增的记录与主表关系起来。你明白了吗?

            这里我要强调一点,两表关联,对应该的关系ID要统一。比如主表中的主键是 classId ,那么相关系的从表关联id 也应该是classId,如果不统一的话,EF很难自动进行Map,除非人为的在Map文件中重改映射关系。

     

        (3)、修改关系数据 (Changing a Relationship Between Objects)

          private static void ChangeLodgingDestination()
          {
            using (var context = new BreakAwayContext())
            {
              var hotel = (from l in context.Lodgings
                      where l.Name == "Grand Hotel"
                      select l).Single();
              var reef = (from d in context.Destinations
                      where d.Name == "Great Barrier Reef"
                      select d).Single();
              hotel.Destination = reef;
              context.SaveChanges();
            }
          }

    这是生成Sql语句:
        exec sp_executesql N'update [dbo].[Lodgings]
        set [destination_id] = @0
        where ([LodgingId] = @1)
        ',N'@0 int,@1 int',@0=4,@1=1

           这里Lodgings依然扮演着从表的角色,代码暂示了主从表关系的变更。当然,这只是DBContext中给我们提供的一个解决方案。我个人习惯直接修改关联关系ID的值。

     

        (4)、删除关系(Removing a Relationship Between Objects)

          private static void RemovePrimaryContact()
          {
            using (var context = new BreakAwayContext())
            {
              var davesDump = (from l in context.Lodgings
                        where l.Name == "Dave's Dump"
                        select l).Single();
              context.Entry(davesDump).Reference(l => l.PrimaryContact).Load();
              davesDump.PrimaryContact = null;
              context.SaveChanges();
            }       }

     

          private static void RemovePrimaryContact()
          {
            using (var context = new BreakAwayContext())
            {
              var davesDump = (from l in context.Lodgings
                        where l.Name == "Dave's Dump"
                        select l).Single();
              davesDump.PrimaryContactId = null;
              context.SaveChanges();
            }
          }

                   删除关系没什么好讲的,一种方式是关联子集置空,一种方式是将关联id置空。


                (5)、简单描述一下跟踪状态,这里只是简单的了解,后续会有专门的详解。(Working with Change Tracking)

                   状态清单:• DbSet.Add
               • DbSet.Find
               • DbSet.Remove
               • DbSet.Local
               • DbContext.SaveChanges
               • Running any LINQ query against a DbSet
               • DbSet.Attach
               • DbContext.GetValidationErrors
               • DbContext.Entry
               • DbChangeTracker.Entries

                  正是有了这些跟踪状态(Tracking),SaveChanges才知道它应该干些什么。

          

          DetectChanges:变化检测(Controlling When DetectChanges Is Called) 控制程序将在 变化检测时被触发。

               大多数情况下(或者说大多说时间),在SaveChanges期间 Entity Framework 都需要知道 Tracking Change(即跟踪状态的改变情况)。     这里有个不太好理解的定义:Automatic DetectChanges 下面是一段应用代码,因为目前我对Automatic DetectChanges还不太准确。所以只把代码展示出来,大家分析分析。      

          private static void ManualDetectChanges()
          {
            using (var context = new BreakAwayContext())
            {
              context.Configuration.AutoDetectChangesEnabled = false;
              var reef = (from d in context.Destinations
                      where d.Name == "Great Barrier Reef"
                      select d).Single();
              reef.Description = "The world's largest reef.";
              Console.WriteLine(
                "Before DetectChanges: {0}",
                  context.Entry(reef).State);
                  context.ChangeTracker.DetectChanges();
                  Using Snapshot Change Tracking | 61
              Console.WriteLine(
                "After DetectChanges: {0}",
                  context.Entry(reef).State);
            }
          }

                  

          private static void AddMultipleDestinations()
          {
            using (var context = new BreakAwayContext())
            {
              context.Configuration.AutoDetectChangesEnabled = false;
              context.Destinations.Add(new Destination
              {
                Name = "Paris",
                Country = "France"
              });
              context.Destinations.Add(new Destination           {             Name = "Grindelwald",             Country = "Switzerland"           });           context.Destinations.Add(new Destination           {             Name = "Crete",             Country = "Greece"           });           context.SaveChanges();         }       }

         我总觉得这个很难理解。

        (6)、使用detectchanges触发关系 (Using DetectChanges to Trigger Relationship Fix-up) (这个也是我目前不太理解的,下面是实例中的代码)

          private static void DetectRelationshipChanges()
          {
            using (var context = new BreakAwayContext())
            {
              var hawaii = (from d in context.Destinations
                      where d.Name == "Hawaii"
                      select d).Single();
              var davesDump = (from l in context.Lodgings
                      where l.Name == "Dave's Dump"
                      select l).Single();
              context.Entry(davesDump)
                  .Reference(l => l.Destination)
                  .Load();
              hawaii.Lodgings.Add(davesDump);
              Console.WriteLine(
                  "Before DetectChanges: {0}",
                    davesDump.Destination.Name);
                    context.ChangeTracker.DetectChanges();
              Console.WriteLine(
                  "After DetectChanges: {0}",
                    davesDump.Destination.Name);
            }
          }

          希望代码能让我们明白其中的道理。

            (7)、启用和使用更改跟踪代理 (Enabling and Working with Change Tracking Proxies)

             (8)、确保新实例获取代理 (Ensuring the New Instances Get Proxies)

             (9)、创建派生类型的代理实例(Creating Proxy Instances for Derived Types)

         (10)、不更改跟踪获取实体 (Fetching Entities Without Change Tracking)

           

             小述:6、7、8、9、10 这几种方式我没有用到,也不知道他们有什么好处和优点。如果大家了解的话,请告诉我。我先将自己用过和理解的写错来。对于一些未知的领域,也希望大家不吝指教。好了,就写到这里,我是百灵。

    百灵注:本文版权由百灵和博客园共同所有,转载请注明出处。
    助人等于自助!  mbailing@163.com

  • 相关阅读:
    训练总结
    图论--最短路--SPFA模板(能过题,真没错的模板)
    图论--最短路-- Dijkstra模板(目前见到的最好用的)
    The 2019 Asia Nanchang First Round Online Programming Contest B Fire-Fighting Hero(阅读理解)
    关于RMQ问题的四种解法
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 K题 center
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 XKC's basketball team
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 D Carneginon
    ZOJ 3607 Lazier Salesgirl (枚举)
    ZOJ 3605 Find the Marble(dp)
  • 原文地址:https://www.cnblogs.com/mbailing/p/2618097.html
Copyright © 2011-2022 走看看