• Entity Framework想说爱你不容易,这么多的报错,这么多的限制,该如何解决?


    首先看一下采用MODEL FIRST的方式设计的实体模型对象关系图:

    注意:EntityOne中有导航属性:EntityTwo

    在如下代码中的几种情况进行新增操作,均会报错,新增都不会成功:

     static void Main(string[] args)
            {
                Model1Container context = new Model1Container();
    
                //第一种情况:EntityOne有导航属性EntityTwo ,新增时必需同时指定新增的EntityTwo ,否则报错:“Model1Container.EntityOnes”中的实体参与“EntityOneEntityTwo”关系。找到 0 个相关的“EntityTwo”。应有 1 个“EntityTwo”。
                var objSetOne = context.EntityOnes;
                //objSetOne.MergeOption = MergeOption.NoTracking;
                objSetOne.AddObject(new EntityOne() { ID = 2, P1 = "pp1", P2 = "pp2", P3 = "pp3"});
                context.SaveChanges();
    
                
               //第二种情况:有些时候,我们的EntityTwo可能需要先创建,但这样执行同样报错:“Model1Container.EntityTwos”中的实体参与“EntityOneEntityTwo”关系。找到 0 个相关的“EntityOne”。应有 1 个“EntityOne”。
                var objSetTwo = context.EntityTwos;
                //objSetTwo.MergeOption = MergeOption.NoTracking;
                objSetTwo.AddObject(new EntityTwo() { ID = 2, T1 = "tt1", T2 = "tt2", T3 = "tt3" });
                context.SaveChanges();
    
               //第三种情况:有些时候,我们的EntityTwo可能已经在之前已经创建了,此处只是查询出来,用来在需要新增EntityOne时赋值给关联属性:EntityTwo,但依旧报错:“EntityOneEntityTwo”AssociationSet 中的关系处于“Deleted”状态。如果有多重性约束,则相应的“EntityOne”也必须处于“Deleted”状态。
               var objSetTwo = context.EntityTwos;
                var entityTwo = objSetTwo.Single(t=>t.ID==2);
    
                var objSetOne = context.EntityOnes;
                //objSetOne.MergeOption = MergeOption.NoTracking;
                objSetOne.AddObject(new EntityOne() { ID = 3, P1 = "pp1", P2 = "pp2", P3 = "pp3", EntityTwo = entityTwo });
                context.SaveChanges();
    
    
    
            }
    

    只有一种情况才能正确执行新增,如下:

    Model1Container context = new Model1Container();
    
                var objSetOne = context.EntityOnes;
                objSetOne.AddObject(new EntityOne() { ID = 2, P1 = "pp1", P2 = "pp2", P3 = "pp3", EntityTwo = new EntityTwo() {ID=2, T1 = "tt1", T2 = "tt2", T3 = "tt3" } });
                context.SaveChanges();
    

    说明只有同时完成新增EntityOne与关联属性EntityTwo,才能成功,但现实是这样的吗?比如:一个人先后写了几本书,那肯定是先有人这个实体,然后才会有书这个实体,每写一本书,书的作者关联属性应该是人这个实体,但按照上面的测试,新增一本书就必需新增一个人,这显然是不对的,该如何解决呢?我目前没有找到更好的解决办法,唯一的办法就是不要导航,但这又不符合面向对象原则,所以在此还请大家多多指教,谢谢!

    解决方案分享:

    通过网友评论指点,我将两个实体的关联关系,由原来的1:1改为1:0,这样第一种与第三种方式是没有问题的,第二种依然存在问题,因为第二种方式只创建被关联的实体EntityTwo,而EntityTwo可有一个外键字段EntityOneEntityTwo_EntityTwo_ID,若没有相应的EntityOne的ID,是无法创建成功的,也就是说第二种方式只有给定外键的值,才有可能创建成功。算是都解决了。但仍存在一个问题,正如上面我举的例子,人与书,人可以不知道会以后会写书,也就是人不用关联书,但书写出来一定是有人的,也就是书的作者一定是关联人的,人可以写多本书,多本书的作者可以都是同一个人,然而上面采用MODEL FIRST生成的实体,是不能满足人与书这种关系的,需要进行调整,调整如下图示:

     

    这样设定好关系后,再用上面的三种方式来进行操作,都可以通过了:

               // 第一种:创建单个人对象
                //var objSetPerson = context.Persons;
                //objSetPerson.AddObject(Person.CreatePerson(1,"梦在旅途"));
                //context.SaveChanges();
    
    
                //第二种:创建书,并同时指定书的作者ID
                //var objSetBook = context.Books;
                //objSetBook.AddObject(Book.CreateBook(1,".NET学习1.0",1));
                //context.SaveChanges();
    
    
                //第三种:查询到指定的人,并在创建书的同时指定人实体
                var objSetPerson = context.Persons;
                Person person = objSetPerson.Single(t => t.ID == 1);
                var objSetBook = context.Books;
                objSetBook.AddObject(new Book() { ID = 2, Name = ".NET学习2.0", AuthorInfo=person });
                context.SaveChanges();
    

      

  • 相关阅读:
    C# WM_NCMOUSELEAVE 消息触发
    C#常用集合的使用(转载)
    关于直播,所有的技术细节都在这里了(转载)
    C# Winform 窗体美化
    正则表达式符号全解析
    C#中List<T>转DataTable
    C#中的Queue集合
    C#中Stack集合
    智能信息处理
    Mysql
  • 原文地址:https://www.cnblogs.com/zuowj/p/4655254.html
Copyright © 2020-2023  润新知