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 ...
随机推荐
- Appium python自动化测试系列之移动自动化测试前提(一)
1.1 移动自动化测试现状 因为软件行业越来越发达,用户的接受度也在不断提高,所以对软件质量的要求也随之提高,当然这个也要分行业,但这个还是包含了大部分.因为成本.质量的变化现在对自动化测试的重视度越 ...
- FormView控件下DropDownList是否可以绑定
在网站下,FormView控件下是可以通过绑定DropDownList的SelectedValue属性来绑定字段来显示 举例: 1 <asp:DropDownList ID="cboU ...
- 反射型 DDoS 攻击的原理和防范措施
随着僵尸网络的兴起,同时由于攻击方法简单.影响较大.难以追查等特点,分布式拒绝服务攻击(DDoS,Distributed Denial of Service)得到快速壮大和日益泛滥. 成千上万主机组成 ...
- PHP 支付
蚂蚁金服开放平台 2.下载PHP的SDK&demo 3.申请应用 OR 使用沙箱环境 4.生成应用私钥&应用公钥 5.配置config.php 蚂蚁金服开放平台",对,没错, ...
- win10 uwp 俄罗斯方块
俄罗斯方块是一个很经典的游戏,做一个UWP俄罗斯方块没有什么用,我想说的是移植,把经典游戏移植到UWP. 我的所有博客都是抄别人的,这个才是我自己写的.后台很多代码还是抄别人的,我想说的是我们之前有很 ...
- 设置QT应用程序图标方法(Windows下)
学习笔记,言简意赅. 1- 新建文本文件,编辑输入 IDI_ICON1 ICON DISCARDABLE "./image/WindowIco.ico" 注意: ...
- eclispe中安装hibernate插件
用eclispe玩ee的朋友,写配置文件的时候没有提示非常苦恼,而配置dtd文件还是没有得到解决,最后试了试安装插件解决了问题 地址:http://download.jboss.org/jbossto ...
- Java基础(00)
Java发展史 Java之父:詹姆斯.高斯林(James Gosling). SUN(Stanford University Network 斯坦福大学网络公司)产物. 1995年5月23日,java ...
- CentOS 7 校对时间 修改时区
在 CentOS 7 中, 引入了一个叫 timedatectl 的设置设置程序. 用法很简单: timedatectl # 查看系统时间方面的各种状态 Local time: 四 2014-12-2 ...
- JavaScript判断变量数据类型
一.JS中的数据类型 1.数值型(Number):包括整数.浮点数. 2.布尔型(Boolean) 3.字符串型(String) 4.对象(Object) 5.数组(Array) 6.空值(Null) ...