ef设置非自增长id_【EF】EntityFramework 更新数据库字段的三种方法

一、EF更新数据库字段的三种方法

实体类

public class TestDbContext : DbContext

{

public DbSet Tests { get; set; }

public TestDbContext() : base() { }

}

public class Test

{

public long ID { get; set; }

public string Name { get; set; }

public string Email { get; set; }

public string Remarks { get; set; }

}

创建数据

TestDbContext db = new TestDbContext();

db.Tests.Add(new Test() { Name = "测试1", Email= @"123@abc.com", Remarks = "测试1备注"});

db.Tests.Add(new Test() { Name = "测试2", Email = @"456@abc.com", Remarks = "测试2备注"});

db.SaveChanges();

第一种方法:

先查询记录,然后修改相应的属性。此方法虽然多了一个查询步骤,但是也由此利用了EF的自动跟踪功能,后续操作比较方便。

比如,生成的SQL语句只会去修改相应的修改过的字段。

而且经测试发现,如果实体属性值没有改变,不会生成SQL语句,比如将下面的代码执行两次,第二次 SaveChanges() 方法不会执行SQL更新语句(注:由于还是会执行一次查询,所以运行效率并没有显著提升)

TestDbContext db = new TestDbContext();

var test = db.Tests.Find(1);

test.Remarks = "更新字段方法1";

db.SaveChanges();

第二种方法:

直接创建一个新的实体类,然后修改实体对象的状态。此方法虽然少了一个查询步骤,但生成的SQL语句将会修改全部字段,而且还要确保 ID 值存在。(注意:由于会修改全部字段,没有设置的字段会被设置为null)

TestDbContext db = new TestDbContext();

Test test = new Test() { ID = 1, Remarks = "更新字段方法2" };

db.Entry(test).State = System.Data.Entity.EntityState.Modified;

db.SaveChanges();

第三种方法:

创建一个实体类,将实体附加到数据库上下文,然后修改相应属性值的修改标识为 true ,此方法生成的SQL语句与第一种方法一样,比较简洁,而且还少了查询步骤,只是后续的操作比较麻烦,因为要手动设置各个属性的修改标识,还要确保 ID 值存在。

TestDbContext db = new TestDbContext();

Test test = new Test() { ID = 1, Remarks = "更新字段方法3" };

db.Tests.Attach(test);

db.Entry(test).Property("Remarks").IsModified = true;

db.SaveChanges();

生成的SQL语句(使用 SQL Server Profiler 跟踪数据库所得):

第一种方法:(注:第一种方法的代码执行一次后再次执行没有跟踪到更新数据库的SQL语句)

exec sp_executesql N‘UPDATE [dbo].[Tests]

SET [Remarks] = @0

WHERE ([ID] = @1)

‘,N‘@0 nvarchar(max) ,@1 bigint‘,@0=N‘更新字段方法1‘,@1=1

第二种方法:(注:查看SQL语句可知,使用此方法如果不注意可能会导致数据被错误修改)

exec sp_executesql N‘UPDATE [dbo].[Tests]

SET [Name] = NULL, [Email] = NULL, [Remarks] = @0

WHERE ([ID] = @1)

‘,N‘@0 nvarchar(max) ,@1 bigint‘,@0=N‘更新字段方法2‘,@1=1

第三种方法

exec sp_executesql N‘UPDATE [dbo].[Tests]

SET [Remarks] = @0

WHERE ([ID] = @1)

‘,N‘@0 nvarchar(max) ,@1 bigint‘,@0=N‘更新字段方法3‘,@1=1

二、EF中添加记录时获取自增ID值

Entity Framework在将数据插入数据库时,如果主键字段是自增标识列,会将该自增值返回给实体对象对应的属性。

比如下面添加博客随笔至数据库的示例代码:

var blogPost = new BlogPost()

{

Author = "博客园",

Title = "程序员的网上家园"

};

using (BlogDbContext context = new BlogDbContext())

{

context.BlogPosts.Add(blogPost);

context.SaveChanges();

return blogPost.ID;

}

SaveChanges()之后,blogPost.ID的值就是数据库中对应自增标识列的值。

看一下Entity Framework生成的SQL语句:

exec sp_executesql N'insert [dbo].[blog_Content]([Title],[Author])

values (@0, @1)

select [ID]

from [dbo].[blog_Content]

where @@ROWCOUNT > 0 and [ID] = scope_identity()',

N'@0 nvarchar(128),@1 nvarchar(128),',@0=N'程序员的网上家园',@1=N'博客园'

EF通过scope_identity()获取自增列的值,而且我们没有对BlogPost的ID属性进行任何设置,是EF智能地判断出ID就是自增标识列。

在以前没有使用Entity Framework的时代,用的是存储过程,存储过程有一堆参数,实体对象的属性值要一一对应地赋值给这些参数,执行存储过程之后,还要通过ParameterDirection.Output的参数获取自增ID的值。

三、EF中 一例对一个或多个实体的验证失败。有关详细信息,请参阅“EntityValidationErrors”属性的解决

注:add数据时 最好加异常捕获(以防一些必填字段没有赋值)

这个问题相信只要是做MVC的,都碰到过,也都知道错误的原因,就是触发了定义的实例字段校验规则。比如定义的不为空,但是为空了,或者定义的字段长度为50,但是超过50了。

可是有时虽然知道是这样,但是具体问题解决的时候还是无从下手。我最近就碰到一个,知道是在更新某个表的时候出现的这个问题。可是在本地无法具现此错误,这个错误是在特定条件发生的,我并不知道此特定发生条件是什么,很郁闷。

在网上找了下,知道发生这个错误会触发DbEntityValidationException异常,这个异常会有详细的异常信息说明是哪个字段,出现了什么错误,只不过需要循环输出。打算输出到日志文件中看是什么错误。代码如下:

try

{

es2.Update(examList);

}

catch (DbEntityValidationException dbEx)

{

foreach (var validationErrors in dbEx.EntityValidationErrors)

{

foreach (var validationError in validationErrors.ValidationErrors)

{

EventLog.Log(string.Format("Class: {0}, Property: {1}, Error: {2}", validationErrors.Entry.Entity.GetType().FullName,

validationError.PropertyName,

validationError.ErrorMessage), "error");

}

}

}

catch (Exception ex)

{

throw;

}

finally

{

}

之所以用2个catch,是为了防止有其他非DbEntityValidationException 错误时,没有错误日志。

DbEntityValidationException所在命名空间:System.Data.Entity.Validation

编译,上传到服务器,过了一会,查看日志文件,找到错误原因了。

Class: System.Data.Entity.DynamicProxies.ExamList_839A196D8FC4CF7E8A791B7F29782BA535E73532A1C3C2C00FD6EF30B6C4A660, Property: StudentAnswer, Error: 字段 StudentAnswer 必须是最大长度为 50 的字符串。

是StudentAnswer 字段长度不够了。

EntityFramework 更新数据库字段的三种方法

例: 实体类: public class TestDbContext : DbContext { public DbSet Tests { get; set; } public ...

Oracle数据库备份与恢复的三种方法

转自blueskys567原文Oracle数据库备份与恢复的三种方法, 2006-10. 有删改 Oracle数据库有三种标准的备份方法,它们分别是导出/导入(EXP/IMP).热备份和冷备份. 导出 ...

hibernate update 只更新部分字段的3种方法(转载)

hibernate 中如果直接使用 Session.update(Object o); 会把这个表中的所有字段更新一遍. 比如: public class Teacher Test { @Test p ...

hibernate update 只更新部分字段的3种方法(其实我只想说第二种)

hibernate 中如果直接使用Session.update(Object o);会把这个表中的所有字段更新一遍. 比如: public class Teacher Test { @Test pub ...

MySQL数据库改名的三种方法

前不久去面试,被问到Innodb引擎的表如何改数据库名,当时我也只回答了MyISAM改如何操作,被一些细节问题打败,真是操蛋. 如果表示MyISAM那么可以直接去到数据库目录mv就可以. Innodb ...

Entity Framework 数据库初始化的三种方法

在数据库初始化产生时进行控制,有三个方法可以控制数据库初始化时的行为.分别为CreateDatabaseIfNotExists.DropCreateDatabaseIfModelChanges.Dro ...

查看sql server数据库连接数的三种方法

怎样才能查看sql server数据库连接数呢?下面就将为您介绍三种查看的方法,供您参考,希望能够帮助到您. 1.通过系统的“性能”来查看:开始->管理工具->性能(或者是运行里面输入 m ...

Oracle数据库分页的三种方法

-- 不能对ROWNUM使用>(大于1的数值).>=(大于或等于1的数值).=(大于或等于1的数值),否则无结果-- 所以直接用只能从1开始-- rownum >10 没有记录,因为 ...

python更新数据库脚本三种方法

最近项目的两次版本迭代中,根据业务需求的变化,需要对数据库进行更新,两次分别使用了不同的方式进行更新. 第一种:使用python的MySQLdb模块利用原生的sql语句进行更新 import MySQ ...

随机推荐

ajax异步处理时,如何在JS中获取从Servlet或者Action中session,request

ssh项目中,我需要登陆某个页面(如a.jsp),通过onblur()鼠标失去焦点后来触发js函数(函数是ajax请求)请求到相应的action,处理完成后将数据存放到session对象里面,然后在a ...

spring 的properties解析

一般使用PropertyPlaceholderConfigurer来替换占位符,例如: 字 符 串 其中   就表示空格.如果直接在里面键入空格,无论多少空格都只会显示一个. 用的XML转 ...

siblings()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值