陷阱~EF中的Update与Insert共用一个数据上下文
事情是这样的,有一个列表,里面有很多用户信息,可能会有重复的用户,将这个列表的用户插入到数据表中,如果用户已经存在,就更新这个用户的FillTimes 字段,让它加1,使用的底层ORM是entity frameworks4。
这是方法的大概内容
var user_Account = iC_User_Account.Find(i => i.UserID == u.UserID);
if (user_Account == null)
{
iRepository.Insert(new C_User_Account
{
AccountID = ,
AddTime = rechargeTime,
BeginDate = rechargeTime,
EndDate = rechargeTime.AddYears(),
FillTimes = ,
Income = ,
Incoming = ,
LockMoney = ,
Outgoings = card.CardValue,
Status = ,
UserID = u.UserID,
UserType = ,
});
}
else
{ user_Account.FillTimes = user_Account.FillTimes ?? + ;
iRepository.Update(user_Account);
}
这个方法看似没有任何问题,当一个用户没有在表中存在,就insert,如果存在了,就update,这是再简单不过的逻辑了,然而,如果你的iRepository对象声明
放错了位置,可能问题就出来了,我们知道DbContext是有缓存的,当一个实体被提交后,它可能在缓存里还会存在,直到DbContext被dispose之后,它才会
消失,这就是说,如果insert与update使用的是同一个DbContext,就会出现一个异常,“不能在相同的对象上建立新实体”,而一般地,insert与update不能不同存在,这是我们可以想像的,而我们可能往往忽略了DbContext是否为一个,如果insert或者update之后,DbContext对象没有被销毁,那异常就会出现了。
而在本例中,iRepository的声明与实例化是在方法体外部完成的,而这个方法就是在被集合遍历时调用的,这时,你的iRepository里的DbContext对象就成了一个,在这个方法的生命周期时,你的数据上下文是一个,你的update操作也就出现问题了,呵呵。
//定义一个数据操作对象
var iRepository=new Repository<User>(); //供外部调用的更新用户列表的方法
public void UpdateUser(List<User> list)
{
userList.ForEach(i=>{
InsertOrUpdateUser(i);
});
}
如果你的代码是这样写的话,那在遍历调用 InsertOrUpdateUser方法时,就有可能出现上面的异常了,呵呵!
正确的作法是将var iRepository=new Repository<User>();这句话移到InsertOrUpdateUser方法体里,问题就解决了。
陷阱~EF中的Update与Insert共用一个数据上下文的更多相关文章
- 在EF中使用原生SQL,首先要创建上下文对象
using (var db = new Entities()) { //数据操作 } 新增 string sql = "insert into UserInfo values('zhangs ...
- EF中的transaction的使用范例
注意一点: 在EF中使用事物后,对于一个新增的model,在saveChanges后,可以得到该实体的自增ID,但在提交事物之前, 该数据并没有真正的新增到DB中,但此时可以得到model新增的自增I ...
- ABP Framework:移除 EF Core Migrations 项目,统一数据上下文
原文:Unifying DbContexts for EF Core / Removing the EF Core Migrations Project 目录 导读:软件开发的一切都需要平衡 动机 警 ...
- 在Sql Server触发器中判断操作是Insert还是Update还是Delete
在Sql Server触发器中判断操作是Insert还是Update还是Delete DECLARE @IsInsert bit, @IsUpdate bit, @IsDelete ...
- EF4.1: Add/Attach and Entity States(EF中的实体状态转换说明)
实体的状态,连接以及 SaveChanges 方法 数据库上下文对象维护内存中的对象与数据库中数据行之间的同步.这些信息在调用 SaveChanges方法被调用的时候使用.例如,当使用 Add 方法传 ...
- Entity Framework入门教程(3)---EF中的上下文简介
1.DbContext(上下文类) 在DbFirst模式中,我们添加一个EDM(Entity Data Model)后会自动生成一个.edmx文件,这个文件中包含一个继承DbContext类的上下文实 ...
- easyui datagrid 禁止选中行 EF的增删改查(转载) C# 获取用户IP地址(转载) MVC EF 执行SQL语句(转载) 在EF中执行SQL语句(转载) EF中使用SQL语句或存储过程 .net MVC使用Session验证用户登录 PowerDesigner 参照完整性约束(转载)
easyui datagrid 禁止选中行 没有找到可以直接禁止的属性,但是找到两个间接禁止的方式. 方式一: //onClickRow: function (rowIndex, rowData) ...
- EF中使用UnitOfWork
前言 关于EF5中使用UnitWork,参见另一博文: https://www.cnblogs.com/masonblog/p/9801162.html 每次提交数据库都会打开一个连接,造成结果是: ...
- EF中执行sql语句,以及事务
EF to sql string sql = "select T_Task.BSID,T_Task.CloseDate,T_Task.CompleteDate,T_Task.CloseUse ...
随机推荐
- 各种python环境的问题
[OS] mac [ERROR] decoder jpeg not available [SOLUTION] $ pip uninstall pillow $ brew install libjpeg ...
- 关于runtime
http://www.jianshu.com/p/ab966e8a82e2 看这个网址即可
- sql server 2008 登录 4064 错误解决办法
出现这个错误是账户无法打开默认数据库导致的 修改一下该账户的默认打开数据库即可. 如果很不幸,你的sa帐号和windows身份验证默认都打开同一个数据库,那么无论换哪种方式登录都是一样没用的 如果你有 ...
- php 正则表达式捕获组与非捕获组
熟练掌握正则表达式是每个程序员的基础要求,对于每个初学者来说会被正则表达式一连串字符弄得头晕眼花.博主便会如此,一直对正则表达式有种莫名的恐惧.近来看到另一位博友写的 <php正则表达式> ...
- ModernUI教程:第一个ModernUI应用(手动编写)
这篇文章带着我们从头开始创建一个Modern UI应用.有关采用项目模板和项模板创建Modern UI应用请参看 第一个ModernUI应用(采用项目模板). 1:获取最新的ModernUI发布并解 ...
- opc 方面研究
http://opcuaservicesforwpf.codeplex.com/ WPF + OPC UA
- [Json.net]Linq to Json
引言 上篇学习了json.net的基本知识,这篇学习linq to json. 上篇文章:[Json.net]快速入门 Linq to Json Linq to Json是用来快速操作json对象的, ...
- G-nav-01
<body><header id="masthead" class="masthead" role="banner"> ...
- iOS开发小技巧--利用运行时得到隐藏的成员变量
一.关于运行时,已经从网络上摘抄了一片文章,这里只有项目中自己的简单使用 -- 查找隐藏的成员变量 导入头文件 可以获得隐藏的成员变量,方法,属性等 代码: 打印效果图:
- 大概了解了flexbox
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...