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

简介:

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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();
 
 
 
        }

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

1
2
3
4
5
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生成的实体,是不能满足人与书这种关系的,需要进行调整,调整如下图示:

 

 

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 第一种:创建单个人对象
  //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();

  

本文转自 梦在旅途 博客园博客,原文链接:  http://www.cnblogs.com/zuowj/p/4655254.html ,如需转载请自行联系原作者

相关文章
|
应用服务中间件 Linux 网络安全
如何在 CentOS 7 上为 Nginx 创建自签名 SSL 证书
如何在 CentOS 7 上为 Nginx 创建自签名 SSL 证书
465 1
|
9月前
|
存储 机器学习/深度学习 人工智能
【AI系统】完全分片数据并行 FSDP
本文深入探讨了AI框架中针对权重数据、优化器数据和梯度数据的分布式并行实现,特别是在PyTorch框架下的具体方案。文章首先回顾了通用数据并行和分布式数据并行的概念,重点讨论了同步与异步数据并行的差异。接着,文章详细介绍了如何在PyTorch中实现弹性数据并行,特别是完全分片数据并行(FSDP)的机制,包括其如何通过分片模型状态和剩余状态来减少内存消耗,提高训练效率。此外,文章还探讨了混合精度训练、损失缩放和内存消耗估算等关键技术,为理解和实施高效的分布式训练提供了全面的指导。
316 9
【AI系统】完全分片数据并行 FSDP
|
存储 小程序 中间件
浅谈云计算发展演变出的三种服务模式:IaaS,PaaS和SaaS
浅谈云计算发展演变出的三种服务模式:IaaS,PaaS和SaaS
1557 0
浅谈云计算发展演变出的三种服务模式:IaaS,PaaS和SaaS
|
11月前
|
XML Java 编译器
Java学习十六—掌握注解:让编程更简单
Java 注解(Annotation)是一种特殊的语法结构,可以在代码中嵌入元数据。它们不直接影响代码的运行,但可以通过工具和框架提供额外的信息,帮助在编译、部署或运行时进行处理。
222 43
Java学习十六—掌握注解:让编程更简单
|
12月前
|
人工智能 数据中心 芯片
【通义】AI视界|英特尔推出新一代AI芯片挑战英伟达
今日科技热点包括:OpenAI CTO 米亚·穆拉蒂宣布离职,Meta发布多功能Llama 3.2语言模型,扎克伯格因Meta的人工智能策略使个人资产突破2000亿美元,星纪魅族展示AI生态新品如Lucky 08 AI手机及智能穿戴设备,以及英特尔发布Xeon 6 CPU和Gaudi 3 AI加速器挑战英伟达市场地位。这些动态展现了人工智能领域快速发展的趋势及其对科技巨头的影响。
|
数据采集 数据挖掘 数据处理
使用Python和Pandas处理CSV数据
使用Python和Pandas处理CSV数据
263 5
|
Linux 数据库
在Linux中,什么是冷备份和热备份?
在Linux中,什么是冷备份和热备份?
|
人工智能 自然语言处理 搜索推荐
基于阿里云向量检索服务搭建AI智能问答机器人
基于阿里云向量检索服务搭建AI智能问答机器人
123706 38
|
canal 关系型数据库 MySQL
Canal数据同步工具
Canal数据同步工具
281 2
|
安全 编译器 Swift
【Swift开发专栏】Swift的编译优化与构建配置
【4月更文挑战第30天】Swift编译优化与构建配置对开发效率和应用性能至关重要。编译优化包括不同级别的优化、函数内联、泛型特化、尾递归优化、死代码消除和链接时优化。在Xcode的"Build Settings"中可调整相关标志。构建配置涉及Debug与Release模式、自定义配置、条件编译、构建设置和脚本。开发时,应适时测试、选择适当优化级别、避免过度优化,并利用条件编译区分不同版本的代码。有效管理构建设置可提升开发质量和性能。
335 0