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 ...
随机推荐
- iOS将自己的框架更新到cocopods上
第一步 把自己的框架更新到github 上,为了提交地址给他人下载.这里就不详细介绍如何把项目更新到github上了 第二步 这个时候我们的项目已经挂在github上了我们需要给本地的项目新建一个Po ...
- JS全选与不选、反选
思路: 1.获取元素. 2.用for循环历遍数组,把checkbox的checked设置为true即实现全选,把checkbox的checked设置为false即实现不选. 3.通过if判断,如果ch ...
- 页面固定DIV层CSS代码
有时候为了用户体验更好些,网页设计师会把网站导航放在一个固定的DIV层里面,不随滚动条滚动.本方法是利用CSS,position:fixed属性来固定层,fixed是特殊的absolute,即fixe ...
- c语言入门
c 语言现在是一门很流行的语言,它介于汇编语言和高级语言之间,我认为 它属于中级语言,如c语言 的指针 ,位操作符,等,因为接近于汇编语言,c语言的执行代码效率很高 现在大多数的系统 如unix,和l ...
- win10 UWP FlipView
FlipView 可以让用户逐个浏览的项目集合 <FlipView Grid.Row="0" Height="100" Margin="10,1 ...
- 【转】C缺陷和陷阱学习笔记
http://www.cnblogs.com/hbiner/p/3591335.html?utm_source=tuicool&utm_medium=referral 这段时间把<C陷阱 ...
- Cosmos OpenSSD--greedy_ftl1.2.0(二)
FTL的整个流程如下: 下面先来看写的流程: 写的代码如下: if((hostCmd.reqInfo.Cmd == IDE_COMMAND_WRITE_DMA) || (hostCmd.reqInfo ...
- 【转】CPU与内存的那些事
下面是网上看到的一些关于内存和CPU方面的一些很不错的文章. 整理如下: 转: CPU的等待有多久? 原文标题:What Your Computer Does While You Wait 原文地址: ...
- JavaAPI 中 <E> 与 <T> 的含义
今天看集合的代码,发现在泛型的使用时的区别,Collection<E>.List<E>,而Iterator<T>,那么<E>和<T>含义有什 ...
- 如何在openlayer接入矢量数据
先说矢量数据集接入,我们通过GeoJSON的示例代码(http://openlayers.org/en/latest/examples/geojson.html)了解Openlayers的源代码,确定 ...