Entity Framework——常见报错总结
1 实体属性配置为IsRequired()对更新的影响
抛出异常类型DbEntityValidationException
表结构:

实体:
public class User
{
public int Id { get; set; }
/// <summary>
/// 账号
/// </summary>
public string Account { get; set; }
/// <summary>
/// 邮箱
/// </summary>
public string Email { get; set; }
/// <summary>
/// 昵称
/// </summary>
public string Nickname { get; set; }
/// <summary>
/// 头像
/// </summary>
public string AvatarId { get; set; }
/// <summary>
/// 记录插入时间
/// </summary>
public DateTime InsertTime { get; set; }
/// <summary>
/// 记录修改时间
/// </summary>
public DateTime UpdateTime { get; set; }
}
实体配置:
modelBuilder.Entity<User>().Property(u => u.Account)
.IsRequired()
.IsUnicode(false)
.HasMaxLength();
modelBuilder.Entity<User>().Property(u => u.Email)
.IsRequired()
.IsUnicode(false)
.HasMaxLength();
modelBuilder.Entity<User>().Property(u => u.Nickname)
.IsUnicode(false)
.HasMaxLength();
modelBuilder.Entity<User>().Property(u => u.AvatarId)
.IsOptional()
.HasMaxLength();
CustomDbContext继承自DbContext
[DbConfigurationType(typeof(MySqlEFConfiguration))]
public class CustomDbContext : DbContext
{
public CustomDbContext()
: base("name=Master")
{ this.Configuration.LazyLoadingEnabled = false;
//DropCreateDatabaseIfModelChanges
//new DropCreateDatabaseAlways<CustomDbContext>()
Database.SetInitializer<CustomDbContext>(null);
} public DbSet<User> Users { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
EntityConfiguration.Set(modelBuilder);
}
}
更新操作:
using (CustomDbContext db = new CustomDbContext())
{
User user = new User
{
Id = ,
Email = "test@1622.com",
};
DbEntityEntry<User> entry = db.Entry<User>(user);
entry.State = EntityState.Unchanged;
entry.Property(t => t.Email).IsModified = true; int num = db.SaveChanges();
}
执行操作,报错信息如下:

查看EntityValidationErrors,
只能看到{System.Data.Entity.Validation.DbEntityValidationResult},没有更详细的信息。
如果将上述代码用try..catch包起来,如下写法:
try
{
//执行代码
}
catch (DbEntityValidationException ex)
{
var e = ex.EntityValidationErrors;
}
catch (Exception ex)
{
}
一层一层地打开,看到真正导致异常的原因,看到下面的截图:

分析实体配置发现,Account属性被设置为IsRequired,那么在更新实体的时候,即使不更新这个字段,也要给这个字段赋值,那么赋值后观察:
更新操作代码变为
using (CustomDbContext db = new CustomDbContext())
{
User user = new User
{
Id = ,
Email = "test@1622.com",
Account = "a"
};
DbEntityEntry<User> entry = db.Entry<User>(user);
entry.State = EntityState.Unchanged;
entry.Property(t => t.Email).IsModified = true; int num = db.SaveChanges();
}
经过上述调整后,更新成功。
那么换一个思路,将Account属性被设置为IsOptional()是不是也可以呢?
修改实体配置,将Account属性设置按如下修改,并注掉上面的Account = "a"
modelBuilder.Entity<User>().Property(u => u.Account)
.IsOptional()
.IsUnicode(false)
.HasMaxLength(50);
执行测试,更改成功。
得出结论:在实体配置时,指定了为必选的字段,那么更新操作时,构造实例一定要对必选(IsRequired())字段赋值。
上述测试中还有一个值得考虑的细节,构造User实例的时候,只对Id,Email进行了赋值,而没有对其他属性进行赋值,那么为什么会成功呢?那么必定是未进行任何设置的实体属性默认是IsOptional()。这跟表结构中的字段类型设置为Not Null有无关联呢,从测试结果看就本类应用无必然联系。
总结:
a.实体配置中指定了实体属性为IsRequired(),更新操作构造类的实例时必对此属性赋值。
b.不进行配置的实体属性默认为IsOptional()
c.表结构中字段是否为Not Null对上述规则无影响。
2 更新报错:
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
异常类型:System.Data.Entity.Infrastructure.DbUpdateConcurrencyException
实体属性配置如上例所示。
操作代码:
using (CustomDbContext db = new CustomDbContext())
{
User user = new User
{
Id = ,
Email = "test@132.com",
};
DbEntityEntry<User> entry = db.Entry<User>(user);
entry.State = EntityState.Unchanged;
entry.Property(t => t.Email).IsModified = true; User user1 = new User
{
Id = ,
Email = "test@132.com",
};
DbEntityEntry<User> entry1 = db.Entry<User>(user1);
entry1.State = EntityState.Unchanged;
entry1.Property(t => t.Email).IsModified = true; int num = db.SaveChanges();
}
执行操作

涉及到两次修改操作,两次操作构造了两个实例,但是实例的属性Id有相同的值。
如果两次操作的是同一个实例,而不是不同的实例,那么不会抛出异常,代码如下:
using (CustomDbContext db = new CustomDbContext())
{
User user = new User
{
Id = ,
Email = "test@132.com",
};
DbEntityEntry<User> entry = db.Entry<User>(user);
entry.State = EntityState.Unchanged;
entry.Property(t => t.Email).IsModified = true; DbEntityEntry<User> entry1 = db.Entry<User>(user);
entry1.State = EntityState.Unchanged;
entry1.Property(t => t.Email).IsModified = true; int num = db.SaveChanges();
}
3 未给主键赋值或赋给主键一个不存在的值,抛出异常
System.Data.Entity.Infrastructure.DbUpdateConcurrencyException
操作代码如下,其中Id=1这条语句被注掉,Id是主键:
using (CustomDbContext db = new CustomDbContext())
{
User user = new User
{
//Id = 1,
Email = "test@132.com",
};
DbEntityEntry<User> entry = db.Entry<User>(user);
entry.State = EntityState.Unchanged;
entry.Property(t => t.Email).IsModified = true;
int num = db.SaveChanges();
}
运行上述代码,抛出异常信息如下,注意异常类型居然是System.Data.Entity.Infrastructure.DbUpdateConcurrencyException,看上去像是并发问题,但实际却不是!
Message:
Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

赋给主键一个不存在的值,令Id=4(在数据库表中不存在Id为4的一条记录)抛出的异常与上面的相同。
4 字段超长抛出异常:System.Data.Entity.Validation.DbEntityValidationException
表中Nickname 字段定义为50个字符,现在赋值超过50。
操作代码如下:
using (CustomDbContext db = new CustomDbContext())
{
User user = new User
{
Id = ,
Email = "test@132.com",
Nickname = "TestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateError"
};
DbEntityEntry<User> entry = db.Entry<User>(user);
entry.State = EntityState.Unchanged;
entry.Property(t => t.Email).IsModified = true;
int num = db.SaveChanges();
}
运行程序报错:
一层一层点开,查看具体原因:
-----------------------------------------------------------------------------------------
转载与引用请注明出处。
时间仓促,水平有限,如有不当之处,欢迎指正。
Entity Framework——常见报错总结的更多相关文章
- web报表工具FineReport使用中遇到的常见报错及解决办法(二)
web报表工具FineReport使用中遇到的常见报错及解决办法(二) 这里写点抛砖引玉,希望大家能把自己整理的问题及解决方法晾出来,Mark一下,利人利己. 出现问题先搜一下文档上有没有,再看看度娘 ...
- java常见报错及解决
Java常见报错信息: Java 常见异常种类 Java Exception: 1.Error 2.Runtime Exception 运行时异常 3.Exception 4.throw 用户自定 ...
- HDFS集群常见报错汇总
HDFS集群常见报错汇总 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.DataXceiver error processing WRITE_BLOCK operation 报 ...
- 03:git常见报错解决方法
1.1 git常见报错解决方法 1.warning: LF will be replaced by CRLF in .idea/workspace.xml. 参考博客:https://www.cnbl ...
- JavaScript 调试常见报错以及原因
JavaScript 调试常见报错以及原因 测试环境 chrome 版本 66.0.3359.170(正式版本) (64 位) TypeError 类型错误 不是操作符所接受的数据类型. //---- ...
- Nginx 常见报错
Nginx 常见报错 启动报错:[emerg]: bind() to 0.0.0.0:80 failed (98: Address already in use) 原因:这个是nginx重启时经常遇到 ...
- Django 连接 MySQL 数据库及常见报错解决
目录 Django 连接 MySQL数据库及常见报错解决 终端或者数据库管理工具连接 MySQL ,并新建项目所需数据库 安装访问 MySQL 的 Python 模块 Django 相关配置 可能会遇 ...
- C语言开发中常见报错的解决方案
C语言开发中常见报错的解决方案 整理来源于网络,侵权请通知删除.*禁止转载 ---- fatal error C1003: error count exceeds number; stopping c ...
- Git常用命令及常见报错:You have not concluded your merge (MERGE_HEAD exists)、清理无效的远程追踪分支
一.常用命令 切换到master分支:git checkout master 查看已有本地及远程分支:git branch -a(先git pull拉下全部数据) 查看远程分支:git branch ...
随机推荐
- python xml sendEmail
使用python进行发送邮件,研究的主要是用smtplib这个包,具体代码如下,eg: #!/usr/bin/python #coding=utf-8 import smtplib from emai ...
- BAT级别分类
阿里的级别:P为技术岗,M为管理岗.P7是技术专家级别. 阿里级别对应薪资: 百度使用的T系列及对应薪资: 腾讯的T系列及对应薪资:
- android Intent机制详解
http://www.oschina.net/question/565065_67909 http://www.cnblogs.com/hummersofdie/archive/2011/02/12/ ...
- Pyhton编程(三)之Pycharm安装及运算符
一:上节题目解答 1)使用while循环输出 1 2 3 4 5 6 8 9 10(注意:没有7) n=1while n<11: if n==7: pass //pass代码段指代空代码.. e ...
- 【框架学习与探究之AOP--Castle DynamicProxy】
声明 本文欢迎转载,原始地址:http://www.cnblogs.com/DjlNet/p/7603654.html 前言 先说一点废话,在此之前博主也在早期就接触了或者看了些许AOP相关的文章,然 ...
- 线程queue
import queue q = queue.Queue() #模拟队列,先进先出 q.put('first') q.put('second') q.put('third') print(q.get( ...
- java分页算法,传入当前pageIndex,pageSise,dataTotal可计算出页面上显示的页码,和是否启动上一页下一页
public class CalculationPage { private Boolean showStartPagerDot; private Boolean showEndPagerDot; p ...
- How the Intelligent Digital Mesh Will Transform Every Business Layer
The "intelligent digital mesh" is the definitive package for tomorrow's titans of business ...
- servlet的运行工作
我是一个刚学几天的小白,写得不好,如果哪个地方有错误,欢迎你们指出. 在服务器端,我用的是Tomcat作为Servlet 容器,在容器中有一个Servlet接口,你编写一个servlet类放在Tomc ...
- hdu 6215 -- Brute Force Sorting(双向链表+队列)
题目链接 Problem Description Beerus needs to sort an array of N integers. Algorithms are not Beerus's st ...