分享关于Entity Framework 进行CRUD操作实验的结果

我们在使用Entity Framework框架进行CRUD时,经常会出现各种各样的错误,下面请看我的实验结果。

以下是只用一个上下文对象进行操作:

第一次:

            BlogDbContext blog = new BlogDbContext();
            post = blog.Posts.Single(t => t.Id == 2);
            post.AuthorId = 1;
            blog.SaveChanges();

结果:成功

第二次:

            BlogDbContext blog = new BlogDbContext();
            post = blog.Posts.Single(t => t.Id == 2);
            post.Author = blog.Authors.Single(t => t.Id == 3);
            blog.SaveChanges();

结果:成功

第三次:

            BlogDbContext blog = new BlogDbContext();
            post = blog.Posts.Single(t => t.Id == 2);
            post.AuthorId = 1;
            post.Author = blog.Authors.Single(t => t.Id == 4);
            blog.SaveChanges();

结果:失败,报错如下:

Conflicting changes to the role ‘Post_Author_Target‘ of the relationship ‘ConsoleApplication1.DDD.Infrastructure.Post_Author‘ have been detected.

第四次:

            BlogDbContext blog = new BlogDbContext();
            post = blog.Posts.Single(t => t.Id == 2);
            post.Author = new Author() { Id = 4 };
            blog.Entry(post.Author).State = EntityState.Unchanged;
            blog.SaveChanges();

结果:成功

第五次:

            BlogDbContext blog = new BlogDbContext();
            post = blog.Posts.Single(t => t.Id == 2);
            //author = new Author() { Id = 1, Name = "zwj" };//直接实例化或下面查询得出
            author = blog.Authors.AsNoTracking().Single(t => t.Id == 3);
            post.Author = author;
            blog.SaveChanges();

结果:成功,但是Authors表中会新增一笔记录,并将新的ID赋值给Posts表;原因:Author与Post不在同一个上下文中,Post所在的上下文中追踪不到Author的信息,故当成新增。

以下是在两个不同的上下文中进行操作:

第六次:

            BlogDbContext blog = new BlogDbContext();
            post = blog.Posts.AsNoTracking().Single(t => t.Id == 2);
            //blog.Entry(post).State = EntityState.Detached;上面的AsNoTracking可以由这句实现

            BlogDbContext blog2 = new BlogDbContext();
            post.AuthorId = 5;
            blog2.Entry(post).State = EntityState.Modified;
            blog2.SaveChanges();

结果:成功

第七次:

            BlogDbContext blog = new BlogDbContext();
            post = blog.Posts.AsNoTracking().Single(t => t.Id == 2);

            BlogDbContext blog2 = new BlogDbContext();
            post.Author = blog2.Authors.Single(t => t.Id == 5);
            blog2.Entry(post).State = EntityState.Modified;
            blog2.SaveChanges();

结果:失败,报错如下:

A referential integrity constraint violation occurred: The property value(s) of ‘Author.Id‘ on one end of a relationship do not match the property value(s) of ‘Post.AuthorId‘ on the other end.

第八次:

            BlogDbContext blog = new BlogDbContext();
            post = blog.Posts.AsNoTracking().Single(t => t.Id == 2);

            BlogDbContext blog2 = new BlogDbContext();
            author = blog2.Authors.AsNoTracking().Single(t => t.Id == 1);
            post.Author = author;
            blog2.Entry(post).State = EntityState.Modified;
            blog2.SaveChanges();

结果:失败,报错同第七次

第九次:

            BlogDbContext blog = new BlogDbContext();
            post = blog.Posts.AsNoTracking().Single(t => t.Id == 2);
            author = blog.Authors.AsNoTracking().Single(t => t.Id == 3);

            BlogDbContext blog2 = new BlogDbContext();
            post.Author = author;
            blog2.Entry(post).State = EntityState.Modified;
            blog2.SaveChanges();

结果:失败,报错同第七次

第十次:

            BlogDbContext blog = new BlogDbContext();
            post = blog.Posts.AsNoTracking().Single(t => t.Id == 2);

            BlogDbContext blog2 = new BlogDbContext();
            author = new Author() { Id = 1, Name = "zwj" };
            post.Author = author;
            blog2.Entry(post).State = EntityState.Modified;
            blog2.SaveChanges();

结果:失败,报错同第七次

第十一次:

            BlogDbContext blog = new BlogDbContext();
            post = blog.Posts.AsNoTracking().Single(t => t.Id == 2);

            BlogDbContext blog2 = new BlogDbContext();
            author = blog2.Authors.Single(t => t.Id == 1);
            post.Author = author;
            post.AuthorId = author.Id;
            blog2.Entry(post).State = EntityState.Modified;
            blog2.SaveChanges();

结果:成功,但我认为主要是通过赋值AuthorId来完成的,与第六次相同,去掉赋值AuthorId,则与第七次相同的报错

第十二次:

            BlogDbContext blog = new BlogDbContext();
            post = blog.Posts.AsNoTracking().Single(t => t.Id == 2);

            BlogDbContext blog2 = new BlogDbContext();
            author = blog2.Authors.Single(t => t.Id == 3);
            blog2.Entry(post).Reference(t => t.Author).CurrentValue = author;
            blog2.Entry(post).State = EntityState.Modified;
            blog2.SaveChanges();

结果:失败,报错同第七次

第十三次:

            BlogDbContext blog = new BlogDbContext();
            post = blog.Posts.AsNoTracking().Single(t => t.Id == 2);

            BlogDbContext blog2 = new BlogDbContext();
            blog2.Posts.Attach(post);
            post.Author = blog2.Authors.Single(t => t.Id == 1);
            blog2.SaveChanges();

结果:成功

最后得出结论:

1.在同一个上下文中,不论是采用直接赋值导航属性或是直接赋值外键属性,除不能同时对导航属性及外键属性赋不相关联的值外,都可以成功;

2.不在同一个上下文中,若想在完成CUD时,则必需先确保要进行操作的实体处于Detached状态,然后再进行相应的更新,涉及导航属性时,只能采用赋值外键属性,不能通过导航属性直接赋值,否则会报错(这个我觉得是个BUG,不知大家有什么好的解决办法没有),若采用先在新的上下文中Attached,再进行更新操作则与第1条结论相同。

时间: 2024-08-08 13:46:52

分享关于Entity Framework 进行CRUD操作实验的结果的相关文章

[UWP小白日记-11]在UWP中使用Entity Framework Core(Entity Framework 7)操作SQLite数据库(一)

前言 本文中,您将创建一个通用应用程序(UWP),使用Entity Framework Core(Entity Framework 7)框架在SQLite数据库上执行基本的数据访问. 准备: Entity Framework Core(Entity Framework 7)下文将简称:EF 1.在UWP中使用EF需要更新Microsoft.NETCore.UniversalWindowsPlatform到大于“5.2.2”的版本. 2.直接在“程序包管理器控制台”输入命令来更新:Update-P

关于Entity Framework中的Attached报错的完美解决方案

我们在使用Entity Framework进行CRUD时,为了提升查询效率,一般均会启动NoTracking,即不追踪变化,设置代码如下: //这是DB First模式下设置方法: aTestEntities db = new aTestEntities(); db.Companies.MergeOption = MergeOption.NoTracking; //这是CODE First及Model First模式下设置方法: aTestEntities db = new aTestEntit

Asp.Net MVC4开发二: Entity Framework在Asp.Net MVC4中的应用

ORM作为一种数据库访问机制已广泛地应用于各种项目当中,在.Net开发中,应用比较广泛的ORM框架大致有下面几个: 官方支持的有:Linq to SQL,Entity Framework.三方的有:NHibernate.前面介绍过Linq to SQL的应用,这篇介绍一下Entity Framework在Asp.Net MVC4中的应用. 首先用Visual Studio(2012或2013,其它版本需要安装Asp.Net MVC4)创建一个Asp.Net MVC4的项目,项目创建完成后会发现E

什么是Entity Framework(ORM)

高手掠过,仅仅是查漏补缺 Entity Framework是什么: 1,ADO.NET  Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案 2,实体框架Entity Framework 是 ADO.NET 中的一组支持开发面向数据的软件应用程序的技术.是微软的一个ORM框架 题外(ORM了解) 广义上,ORM指的是面向对象的对象模型和关系型数据库的数据结构之间的相互转换. 狭义上,ORM可以被认为是,基于关系型数据库

MVC5 Entity Framework学习之实现主要的CRUD功能

在上一篇文章中,我们使用Entity Framework 和SQL Server LocalDB创建了一个MVC应用程序,并使用它来存储和显示数据.在这篇文章中,你将对由 MVC框架自己主动创建的CRUD(create, read, update, delete)代码进行改动. 注意:通常我们在控制器和数据訪问层之间创建一个抽象层来实现仓储模式.为了将注意力聚焦在怎样使用实体框架上.这里暂没有使用仓储模式. 在本篇文章中,要创建的web页面: watermark/2/text/aHR0cDovL

Mvc5+Entity Framework6 之二----在MVC中用Entity Framework实现基本的CRUD

目标:创建控制器和视图的代码,实现CRUD(创建,读取,更新,删除)功能 创建一个详细信息页 控制器为Students的Index页生成的代码排除Enrollments属性在外,因为该属性中关联着一个集合.而该集合的内容将会在Details页面 <table>标签中显示. 在控制器Controllers\StudentController.cs的代码中使用Find方法为Details视图取出单个Student实体. public ActionResult Details(int? id) {

MVC5 Entity Framework学习之实现基本的CRUD功能

在上一篇文章中,我们使用Entity Framework 和SQL Server LocalDB创建了一个MVC应用程序,并使用它来存储和显示数据.在这篇文章中,你将对由 MVC框架自动创建的CRUD(create, read, update, delete)代码进行修改. 注意:通常我们在控制器和数据访问层之间创建一个抽象层来实现仓储模式,为了将注意力聚焦在如何使用实体框架上,这里暂没有使用仓储模式. 在本篇文章中,要创建的web页面: 1.创建一个Details页面 由框架代码生成的Stud

.NET Entity Framework入门操作

Entity Framework是微软借鉴ORM思想开发自己的一个ORM框架. ORM就是将数据库表与实体对象(相当于三层中的Model类)相互映射的一种思想. 最大的优点就是非常方便的跨数据库平台.因为该技术不需要知道用的是什么数据库,这也是.net中Linq能To任何对象的原因. 这门技术为什么可以跨平台呢?是因为它只需要修改一下config文件就可以了,只要指定连接字符串,驱动程序,就可以根据不同数据库生成不同的Sql语句,当你的项目用户用到不同的数据库时,就不需要像修改SQL语句了. E

《Entity Framework 6 Recipes》中文翻译系列 (20) -----第四章 ASP.NET MVC中使用实体框架之在MVC中构建一个CRUD示例

翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第四章  ASP.NET MVC中使用实体框架 ASP.NET是一个免费的Web框架,它支持3种不同的技术来创建websites(网站)和Web应用:他们分别是,Web Pages,Web Forms,和MVC.虽然MVC是一种非常流行的,有完整的用于软件开发模式理论的技术,但它在ASP.NET中却是一种新的技术. 目前最新的版本是2012年发布的ASP.NET MVC4.自从2008年发布