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

  实体类

   public class TestDbContext : DbContext
{
public DbSet<Test> 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 字段长度不够了。

【EF】EntityFramework 更新数据库字段的三种方法的更多相关文章

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

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

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

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

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

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

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

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

  5. MySQL数据库改名的三种方法

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

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

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

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

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

  8. Oracle数据库分页的三种方法

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

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

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

随机推荐

  1. C++(三十一) — 静态成员变量、静态成员函数

    1.静态成员变量 类的静态成员变量是,由该类的所以对象共同维护和使用的数据成员,每个类只有一个副本,是类数据成员的一种特例.采用 static 关键字声明. 目的:实现同一类中不同对象之间的数据共享. ...

  2. ResultSet 结果集

    转自:http://blog.csdn.net/z93971401/article/details/7469503 这篇文章并没有给出如何使用ResultSet的具体例子,只是从ResultSet的功 ...

  3. UVA-1615 Highway (贪心,区间选点)

    题目大意:有一条沿x轴正方向,长为L的高速公路,n个村庄,要求修建最少的公路出口数目,使得每个村庄到出口的距离不大于D. 题目分析:区间选点问题.在x轴上,到每个村庄距离为D的点有两个(超出范围除外) ...

  4. 关于Mac上使用ideviceinstaller操作iPhoneXR等24位UDID设备报“ERROR: Invalid UDID specified”解决办法

    最近新申请了一台iPhone XR, 测试时发现使用ideviceinstaller命令老是报错: Jackeys-MacBook-Pro:~ jackey$ ideviceinstaller -u ...

  5. Spring源码解析-IOC容器的实现-ApplicationContext

    上面我们已经知道了IOC的建立的基本步骤了,我们就可以用编码的方式和IOC容器进行建立过程了.其实Spring已经为我们提供了很多实现,想必上面的简单扩展,如XMLBeanFacroty等.我们一般是 ...

  6. html/css/javascript练习代码

    这两天心血来潮学习了前端,自己也做了个小小的网页,不好看QAQ 不过网页上集结了很多零碎的知识,在这里先马克一下.图片地址:https://github.com/lesroad/html-css-js ...

  7. rsync的服务端和客户端搭建

    首先要看看有没有rsync,没有就按装一个rsync 1配置文件 然后创建rsyncd.conf文件,并添加如下内容(文件默认不存在) [root@chensiqi2 backup]# cat /et ...

  8. 淘宝TDDL配置以及使用

    此章节具体介绍一下淘宝TDDL具体配置和使用 1. Spring配置文件配置:================spring-mybatis.xml 中配置============= <bean ...

  9. FMDB给表添加新的字段

    1.首先判断添加的字段是否存在,如果不存在就添加. 2.代码演示: (1)判断是否存在,判断之前先导入头文件确保可以调用FMDB的api(#import “FMDatabaseAdditions.h” ...

  10. MBProgressHUD基础用法

    MBProgressHUD版本号:0.9.2以前用MBProgressHUD用得挺好的,基本上 - (void)showAnimated:(BOOL)animated whileExecutingBl ...