ADO.NET Entity Framework学习笔记(3)ObjectContext
ADO.NET Entity Framework学习笔记(3)ObjectContext对象[转]
说明
ObjectContext提供了管理数据的功能

Context操作数据
AddObject 添加实体
|
将实体添加到集合中, 创建实体时,状态为EntityState.Detached 当调用AddObject将实体添加到Context时,状态为EntityState.Added |
|
myContext context = new myContext(); myTab r = new myTab(); r.ID = 10; r.a = "wxwinter"; Console.WriteLine(r.EntityState); //print:Detached context.AddTomyTab(r); Console.WriteLine(r.EntityState); //print:Added context.SaveChanges(); |
|
myContext context = new myContext(); myTab newrow = new myTab() { a = "wxd", b = "lzm", c = "wxwinter" }; context.AddObject("myTab",newrow); context.SaveChanges(); |
DeleteObject 删除实体
|
将集合中的实体添标记为删除 当调用Context.DeleteObject时,并不是将实体移除集合,而是将实体添标记为EntityState.Deleted ,在下次调用SaveChanges()方法时跟新数据库 |
|
myContext context = new myContext(); myTab r = context.myTab.First(p=>p.ID==1); Console.WriteLine(r.EntityState); //print:Unchanged context.DeleteObject(r); Console.WriteLine(r.EntityState); //print:Deleted context.SaveChanges(); |
Detach 分离实体
|
将实体从Context中分离,将状态标记为EntityState.Detached 。 |
|
myContext context = new myContext(); myTab r = myTab.CreatemyTab(22); Console.WriteLine(r.EntityState); //print:Detached context.AddTomyTab(r); Console.WriteLine(r.EntityState); //print:Added context.Detach(r); Console.WriteLine(r.EntityState); //print: Detached |
修改实体
|
可以直接修在实体对象上修改 当修改在Context中的实体时,会将实体的状态标记为EntityState.Modified |
|
myContext context = new myContext(); myTab r = context.myTab.First(p=>p.ID==1); Console.WriteLine(r.EntityState); //print:Unchanged r.a = "wxwinter"; Console.WriteLine(r.EntityState); //print:Modified context.SaveChanges(); |
ApplyPropertyChanges 修改实体
|
使用ApplyPropertyChanges,可以使用不在集合中的实体覆盖到集合中主键对应用实体上,如果内存中没有主键对应的记录,会报错:“ObjectStateManager 不包含具有对“XXX”类型的对象的引用的 ObjectStateEntry。”该方法还有一个特点就是,会拿内存中的对象(新对象)和context中的对象(旧对象)对比,自动生成对应字段修改的Update语句,如果内存中的对象与context中的对象完全相等(每个字段的值都相等),将不生成响应的Update |
|
myContext context = new myContext(); myTab r1 = context.myTab.First(p => p.ID == 1); myTab nr = myTab.CreatemyTab(1); nr.a = "wxwinter"; Console.WriteLine(nr.EntityState); //print:Detached Console.WriteLine(r1.EntityState); //print:Unchanged context.ApplyPropertyChanges("myTab", nr); myTab r2 = context.myTab.First(p => p.ID == 1); Console.WriteLine(nr.EntityState); //print:Detached Console.WriteLine(r2.EntityState); //print:Modified context.SaveChanges(); |
|
Orders order; using (NorthwindEntities ne = new NorthwindEntities()) { //利用EntityObject.Execute(MergeOption.NoTracking),等效于使用ObjectContext.Dettach(EntityObject) //查询并分离对象 order = ne.Orders.Execute(MergeOption.NoTracking).Where(v => v.OrderID == 10248).FirstOrDefault(); } //修改分离的值 order.ShipName = "1111111111111111"; //使用分离的对象 order 更新 using (NorthwindEntities context = new NorthwindEntities()) { //将数据载入到context中以便更新 context.GetObjectByKey(order.EntityKey); //使用order 更新 context中的对应对象 context.ApplyPropertyChanges(order.EntityKey.EntitySetName, order); context.SaveChanges(); } |
Attach / AttachTo 附加实体
使用Attach方法可将[外部实体]附加到Context集合中
在使用 服务器/客户端模式,或要将[实体]从Context集合中分离,修改后要用Context更新回数据库时,可用这种方式
Attach与ApplyPropertyChanges有类似之处,都是将Context集合外的[实体]与Context集合内的[实体]同步.
- ApplyPropertyChanges调用时,要求对应的[实体]在内存中,Attach不要求
- ApplyPropertyChanges调用后,集合内的实体状态会标记为EntityState.Modified Attach调用后不会修改合内的实体状态,如要SaveChanges(),要手动标记EntityState.Modified
- ApplyPropertyChanges是用[外部实体]全覆盖Context集合中的[实体], Attach方式,通过SetModifiedProperty()方法,可在调用SaveChanges()时,只修改只定有字段值
|
myContext context = new myContext(); myTab v = myTab.CreatemyTab(1); v.EntityKey = context.CreateEntityKey("myTab", v); v.a = "wxwinter"; context.Attach(v); //context.AttachTo("myTab", v); ObjectStateEntry ose = context.ObjectStateManager.GetObjectStateEntry(v); //设置修改 ose.SetModified(); //指定修改的字段名 ose.SetModifiedProperty("a"); context.SaveChanges(); |
|
修改前
修改后
|
CreateEntityKey 创建EntityKey
|
myContext context = new myContext(); myTab nr = myTab.CreatemyTab(1); EntityKey ek= context.CreateEntityKey("myTab", nr); |
EntityKey
|
EntityContainerName 属性 |
|
|
EntityKeyValues 集合 |
|
|
EntitySetName 属性 |
|
|
IsTemporary 属性 |
|
|
GetEntitySet(System.Data.Metadata.Edm.MetadataWorkspace) 方法 |
|
|
OnDeserialized(System.Runtime.Serialization.StreamingContext) 方法 |
|
|
OnDeserializing(System.Runtime.Serialization.StreamingContext) 方法 |
GetObjectByKey/TryGetObjectByKey 通过EntityKey得到实体
|
myContext context = new myContext(); myTab nr = myTab.CreatemyTab(1); EntityKey ek= context.CreateEntityKey("myTab", nr); myTab r = context.GetObjectByKey(ek) as myTab ; Console.WriteLine("{0},{1},{2},{3}", r.ID, r.a, r.b, r.c); |
|
myContext context = new myContext(); myTab nr = myTab.CreatemyTab(1); EntityKey ek= context.CreateEntityKey("myTab", nr); object obj; if (context.TryGetObjectByKey(ek,out obj)) { myTab r = obj as myTab; Console.WriteLine("{0},{1},{2},{3}", r.ID, r.a, r.b, r.c); } |
CreateQuery 创建查询
|
更多见esql |
|
myContext context = new myContext(); string esql = "SELECT VALUE DBItemList FROM myContext.DBItemList"; // ObjectQuery<DBItemList> query = new ObjectQuery<DBItemList>(esql, context); ObjectQuery<DBItemList> query = context.CreateQuery<DBItemList>(esql); foreach (DBItemList r in query) { Console.WriteLine(r.NameID); } |
状态管理
EntityState 状态枚举
|
EntityState.Added 已通过AddObject方法加到集合中,AcceptChanges 尚未调用。 EntityState.Deleted 已通过 DeleteObject 方法被删除。 EntityState.Detached 已被创建,但不属于任何集合。在以下情况下立即处于此状态:创建之后添加到集合中之前;或从集合中移除之后。 EntityState.Modified 已被修改,AcceptChanges 尚未调用。 EntityState.Unchanged 自上次调用 AcceptChanges 以来尚未更改 |
Context.ObjectStateManager 管理记录的状态
GetObjectStateEntry 根据实体对象或实体主键得到状态实体
|
ObjectStateEntry = GetObjectStateEntry(实体对像/EntityKey) 得到所指定的[实体对像]或EntityKey的 ObjectStateEntry |
|
myContext context = new myContext(); myTab r = myTab.CreatemyTab(22); context.AddTomyTab(r); // ObjectStateEntry ose= context.ObjectStateManager.GetObjectStateEntry(r); ObjectStateEntry ose = context.ObjectStateManager.GetObjectStateEntry(r.EntityKey); Console.WriteLine(ose.State); //print:Added |
TryGetObjectStateEntry 根据实体对象或实体主键得到状态实体
|
bool = TryGetObjectStateEntry(实体对像/EntityKey,out ObjectStateEntry) 得到所指定的[实体对像]或EntityKey的 ObjectStateEntry |
|
myContext context = new myContext(); myTab r = myTab.CreatemyTab(22); context.AddTomyTab(r); ObjectStateEntry ose; if( context.ObjectStateManager.TryGetObjectStateEntry(r,out ose)) { Console.WriteLine(ose.State); //print:Added } |
GetObjectStateEntries 根据状态类型得到状态实体集合
|
IEnumerable<ObjectStateEntry> = GetObjectStateEntries(EntityState枚举) 返回IEnumerable<ObjectStateEntry>,得到EntityState枚举所指定的某种状态的列表 |
|
myContext context = new myContext(); myTab r = myTab.CreatemyTab(22); context.AddTomyTab(r); IEnumerable<ObjectStateEntry> oseList = context.ObjectStateManager.GetObjectStateEntries(EntityState.Added); foreach (ObjectStateEntry v in oseList) { Console.WriteLine("{0},{1},{2}", v.State, v.CurrentValues["ID"], v.EntitySet.Name); } //print:Added,22,myTab |
ObjectStateManagerChanged 事件
|
CollectionChangeEventHandler(object sender, CollectionChangeEventArgs e) e.Action : 集合操作行为 System.ComponentModel.CollectionChangeAction.Add System.ComponentModel.CollectionChangeAction.Refresh System.ComponentModel.CollectionChangeAction.Remove e.Element : 操作的实体对象 |
|
void ObjectStateManager_ObjectStateManagerChanged(object sender, CollectionChangeEventArgs e) { Console.WriteLine(e.Action); myTab v = e.Element as myTab; Console.WriteLine("{0}",v.ID); } //=================================== myContext context = new myContext(); context.ObjectStateManager.ObjectStateManagerChanged+=new CollectionChangeEventHandler(ObjectStateManager_ObjectStateManagerChanged); myTab r = myTab.CreatemyTab(22); context.AddTomyTab(r); /* *print: Add 22 */ |
ObjectStateEntry 对象
基本属性
|
IsRelationship 属性 |
|
|
Entity 属性 |
|
|
EntityKey 属性 |
|
|
EntitySet 属性 |
State 状态属性
|
EntityState 枚举 |
|
myContext context = new myContext(); myTab r = myTab.CreatemyTab(22); context.AddTomyTab(r); ObjectStateEntry ose= context.ObjectStateManager.GetObjectStateEntry(r); Console.WriteLine(ose.State); //print:Added |
CurrentValues 当前值
|
处于 deleted 或 detached 状态的对象没有当前值。 |
|
myContext context = new myContext(); myTab r = new myTab() { ID = 22, a = "wxwinter" }; context.AddTomyTab(r); ObjectStateEntry ose= context.ObjectStateManager.GetObjectStateEntry(r); Console.WriteLine("{0},{1}",ose.CurrentValues["ID"],ose.CurrentValues["a"]); //print: 22,wxwinter |
OriginalValues 原始值
|
处于 added 或 detached 状态的对象没有原始值 |
|
myContext context = new myContext(); myTab r = context.myTab.First(p => p.ID == 1); r.a = "wxwinter"; ObjectStateEntry ose= context.ObjectStateManager.GetObjectStateEntry(r); Console.WriteLine(ose.State); Console.WriteLine("CurrentValues :{0},{1}", ose.CurrentValues["ID"], ose.CurrentValues["a"]); Console.WriteLine("OriginalValues:{0},{1}", ose.OriginalValues["ID"], ose.OriginalValues["a"]); /* * print: Modified CurrentValues :1,wxwinter OriginalValues:1,aa */ |
GetModifiedProperties 得到被修改的属性
|
返回IEnumerable<string> 得到被修改的属性集合 |
|
myContext context = new myContext(); myTab r = context.myTab.First(p => p.ID == 1); r.a = "wxwinter"; r.b = "wxd"; ObjectStateEntry ose= context.ObjectStateManager.GetObjectStateEntry(r); IEnumerable<string> list = ose.GetModifiedProperties(); foreach (string pr in list) { Console.WriteLine(pr); } /* * print: a b */ |
SetModified,SetModifiedProperty 标记为修改
|
SetModified() 方法将记录标记为 EntityState.Modified 只是这样,调用Context.SaveChanges方法是无法保存修改到数据库中的,Context.SaveChanges方法要查找被修改过的属性, 可用SetModifiedProperty方法标记被修改过的属性 |
|
myContext context = new myContext(); myTab r = context.myTab.First(p => p.ID == 1); r.a = "wxwinter"; ObjectStateEntry ose= context.ObjectStateManager.GetObjectStateEntry(r); ose.AcceptChanges(); Console.WriteLine(ose.State); Console.WriteLine("CurrentValues :{0},{1}", ose.CurrentValues["ID"], ose.CurrentValues["a"]); Console.WriteLine("OriginalValues:{0},{1}", ose.OriginalValues["ID"], ose.OriginalValues["a"]); /* * print: Unchanged CurrentValues :1,wxwinter OriginalValues:1,wxwinter */ ose.SetModified(); ose.SetModifiedProperty("a"); Console.WriteLine(ose.State); Console.WriteLine("CurrentValues :{0},{1}", ose.CurrentValues["ID"], ose.CurrentValues["a"]); Console.WriteLine("OriginalValues:{0},{1}", ose.OriginalValues["ID"], ose.OriginalValues["a"]); /* * print: Modified CurrentValues :1,wxwinter OriginalValues:1,wxwinter */ context.SaveChanges(); |
Delete 标记为删除
|
标记为EntityState.Deleted |
|
myContext context = new myContext(); myTab r = context.myTab.First(p => p.ID == 1); ObjectStateEntry ose= context.ObjectStateManager.GetObjectStateEntry(r); ose.Delete(); Console.WriteLine(ose.State); //print: Detached Console.WriteLine("OriginalValues:{0},{1}", ose.OriginalValues["ID"], ose.OriginalValues["a"]); //print:OriginalValues:1,wxwinter |
|
用 context.DeleteObject方法的效果与上例一样 myContext context = new myContext(); myTab r = context.myTab.First(p => p.ID == 1); ObjectStateEntry ose = context.ObjectStateManager.GetObjectStateEntry(r); context.DeleteObject(r); Console.WriteLine(ose.State); //print: Detached Console.WriteLine("OriginalValues:{0},{1}", ose.OriginalValues["ID"], ose.OriginalValues["a"]); //print:OriginalValues:1,wxwinter |
AcceptChanges 方法
|
将记录的状态置为EntityState.Unchanged 用[CurrentValues 当前值]替换[OriginalValues 原始值], 使用[ Context.AcceptAllChanges 方法]也有同样效果 注意:状态为[EntityState.Deleted ]的记录,会被[Detach] |
|
myContext context = new myContext(); myTab r = context.myTab.First(p => p.ID == 1); r.a = "wxwinter"; context.AcceptAllChanges(); ObjectStateEntry ose= context.ObjectStateManager.GetObjectStateEntry(r); ose.AcceptChanges(); Console.WriteLine(ose.State); Console.WriteLine("CurrentValues :{0},{1}", ose.CurrentValues["ID"], ose.CurrentValues["a"]); Console.WriteLine("OriginalValues:{0},{1}", ose.OriginalValues["ID"], ose.OriginalValues["a"]); /* * print: Unchanged CurrentValues :1,wxwinter OriginalValues:1,wxwinter */ |
|
当调用AcceptChanges时,如果对像处于[EntityState.Deleted ],会将对象移除集合,这时对像的状态为[EntityState.Detached ] myContext context = new myContext(); myTab r = context.myTab.First(p => p.ID == 1); ObjectStateEntry ose= context.ObjectStateManager.GetObjectStateEntry(r); ose.Delete(); ose.AcceptChanges(); Console.WriteLine(ose.State); //print: Detached |
保存修改到数据库
Context.SaveChanges 方法
如果集合中有状态为EntityState.Added的记录,用[CurrentValues 当前值]添加到数据库中
如果集合中有状态为EntityState.Deleted的记录,从数据库是删除与之对应的数据库记录
如果集合中有状态为EntityState.Modified的记录,用[OriginalValues 原始值]与对应的数据库记录比效,查看并发, 用[CurrentValues 当前值]更新与之对应的数据库记录
|
SaveChanges(true) |
将数据保存到数据库后 将所有记录状态标记为EntityState.Unchanged ,(调用Context.AcceptAllChanges ) |
|
myContext context = new myContext(); myTab r = context.myTab.First(p => p.ID == 1); r.a = "wxwinter"; ObjectStateEntry ose = context.ObjectStateManager.GetObjectStateEntry(r); context.SaveChanges(true); Console.WriteLine(ose.State); Console.WriteLine("CurrentValues :{0},{1}", ose.CurrentValues["ID"], ose.CurrentValues["a"]); Console.WriteLine("OriginalValues:{0},{1}", ose.OriginalValues["ID"], ose.OriginalValues["a"]); /* * print: Unchanged CurrentValues :1,wxwinter OriginalValues:1,wxwinter */ |
|
|
SaveChanges() |
与SaveChanges(true)相同 |
|
SaveChanges(false) |
将数据保存到数据库, 但并不改变记录状态 |
|
myContext context = new myContext(); myTab r = context.myTab.First(p => p.ID == 1); r.a = "wxwinter"; ObjectStateEntry ose = context.ObjectStateManager.GetObjectStateEntry(r); context.SaveChanges(false); Console.WriteLine(ose.State); Console.WriteLine("CurrentValues :{0},{1}", ose.CurrentValues["ID"], ose.CurrentValues["a"]); Console.WriteLine("OriginalValues:{0},{1}", ose.OriginalValues["ID"], ose.OriginalValues["a"]); /* * print: Modified CurrentValues :1,wxwinter OriginalValues:1,aa */ |
Context.SavingChanges 事件
|
myContext context = new myContext(); context.SavingChanges+=new EventHandler(context_SavingChanges); myTab r = context.myTab.First(p => p.ID == 1); r.a = "wxwinter"; context.SaveChanges(); |
|
void context_SavingChanges(object sender, EventArgs e) { myContext context = sender as myContext; Console.WriteLine(context.DefaultContainerName); } |
Context.AcceptAllChanges 方法
|
将所有记录的状态置为EntityState.Unchanged 用[CurrentValues 当前值]替换[OriginalValues 原始值] 效果与对所在记录的ObjectStateEntry上调用AcceptAllChanges一样 注意:状态为[EntityState.Deleted ]的记录,会被[Detach] |
|
myContext context = new myContext(); myTab r = context.myTab.First(p => p.ID == 1); r.a = "wxwinter"; context.AcceptAllChanges(); ObjectStateEntry ose= context.ObjectStateManager.GetObjectStateEntry(r); Console.WriteLine(ose.State); Console.WriteLine("CurrentValues :{0},{1}", ose.CurrentValues["ID"], ose.CurrentValues["a"]); Console.WriteLine("OriginalValues:{0},{1}", ose.OriginalValues["ID"], ose.OriginalValues["a"]); /* * print: Unchanged CurrentValues :1,wxwinter OriginalValues:1,wxwinter */ |
连接属性
Context.DefaultContainerName 属性
Context.Connection 属性
Context.CommandTimeout 属性
Context.MetadataWorkspace
数据刷新与并发
EF提供了两种并发冲突处理方式:放任不管方式和开放式并发。默认采用放任不管的方式处理。
如果要使用开放式并发,必须设置相应属性上的[并发模式]值[Fixed]
后修改数据的ObjectContext缓存了旧版本的数据时,当提交修改后系统就会抛出"OptimisticConcurrencyException"(开放式并发异常)。
当程序捕获到异常以后,可以使用ObjectContext的Refresh方法对异常采取处理。


缓存数据不会自动更新
|
公共 |
myContext context1 = new myContext(); myContext context2 = new myContext(); |
|
查询 |
foreach (var r in context1.DBItem) { Console.WriteLine("{0},{1}", r.ItemID, r.ItemMatter); } Console.WriteLine("---------------------"); foreach (var r in context2.DBItem) { Console.WriteLine("{0},{1}", r.ItemID, r.ItemMatter); } |
|
a,this is a b,this is b c,this is c --------------------- a,this is a b,this is b c,this is c |
|
|
修改 |
DBItem dbitem1 = context1.DBItem.First(p => p.ItemID == "a"); dbitem1.ItemMatter = "hello"; context1.SaveChanges(); |
|
再查询 |
foreach (var r in context1.DBItem) { Console.WriteLine("{0},{1}", r.ItemID, r.ItemMatter); } Console.WriteLine("---------------------"); foreach (var r in context2.DBItem) { Console.WriteLine("{0},{1}", r.ItemID, r.ItemMatter); } |
|
a,hello b,this is b c,this is c --------------------- a,this is a b,this is b c,this is c |
[并发模式]值为[Fixed]的并发异常
注意,只有后修改数据的ObjectContext缓存了旧版本的数据时,长会产生异常
|
DBItem dbitem1 = context1.DBItem.First(p => p.ItemID == "a"); dbitem1.ItemMatter = "hello"; context1.SaveChanges(); DBItem dbitem2 = context2.DBItem.First(p => p.ItemID == "a"); dbitem2.ItemMatter = "wxwinter"; context2.SaveChanges(); |
|
|
ObjectContext.Refresh()
Refresh的第一个参数RefreshMode枚举,RefreshMode.StoreWins,RefreshMode.ClientWins
StoreWins
StoreWins : Refresh以后,用数据库的值回写,当前的修改值被放弃
|
公共 |
myContext context1 = new myContext(); myContext context2 = new myContext(); |
|
查询 |
foreach (var r in context1.DBItem) { Console.WriteLine("{0},{1}", r.ItemID, r.ItemMatter); } Console.WriteLine("---------------------"); foreach (var r in context2.DBItem) { Console.WriteLine("{0},{1}", r.ItemID, r.ItemMatter); } |
|
a,this is a b,this is b c,this is c --------------------- a,this is a b,this is b c,this is c |
|
|
修改 |
DBItem dbitem1 = context1.DBItem.First(p => p.ItemID == "a"); dbitem1.ItemMatter = "hello"; context1.SaveChanges(); DBItem dbitem2 = context2.DBItem.First(p => p.ItemID == "a"); dbitem2.ItemMatter = "wxwinter"; try { context2.SaveChanges(); } catch { context2.Refresh( RefreshMode.StoreWins , dbitem2); } |
|
在System.Data.OptimisticConcurrencyException 中第一次偶然出现的"System.Data.Entity.dll"类型的异常 |
|
|
再查询 |
foreach (var r in context1.DBItem) { Console.WriteLine("{0},{1}", r.ItemID, r.ItemMatter); } Console.WriteLine("---------------------"); foreach (var r in context2.DBItem) { Console.WriteLine("{0},{1}", r.ItemID, r.ItemMatter); } |
|
a,hello b,this is b c,this is c --------------------- a,hello b,this is b c,this is c |
ClientWins
StoreWins: Refresh以后,当前的修改值仍存在,只是告诉ObjectContext知到的并发问题了,这时再调用 ObjectContext.SaveChanges()时,ObjectContext就不会报[开放式并发异常]
|
DBItem dbitem1 = context1.DBItem.First(p => p.ItemID == "a"); dbitem1.ItemMatter = "hello"; context1.SaveChanges(); DBItem dbitem2 = context2.DBItem.First(p => p.ItemID == "a"); dbitem2.ItemMatter = "wxwinter"; try { context2.SaveChanges(); } catch { context2.Refresh(RefreshMode.ClientWins, dbitem2); context2.SaveChanges(); } |
|
|
也可以先Refresh()再SaveChanges(),而不用异常捕获
|
DBItem dbitem1 = context1.DBItem.First(p => p.ItemID == "a"); dbitem1.ItemMatter = "hello"; context1.SaveChanges(); DBItem dbitem2 = context2.DBItem.First(p => p.ItemID == "a"); dbitem2.ItemMatter = "wxwinter"; context2.Refresh(RefreshMode.ClientWins, dbitem2); context2.SaveChanges(); |
事务处理
同一SubmitChanges 会做默认的事务处理
下例由于ItemID主键冲突,两条数据都不会被插入
|
myContext context1 = new myContext(); DBItem item1 = new DBItem(); item1.ItemID = "w"; item1.ItemMatter = "wxwinter"; context1.AddObject("DBItem", item1); DBItem item2 = new DBItem(); item2.ItemID = "w"; item2.ItemMatter = "wxd"; context1.AddObject("DBItem", item2); context1.SaveChanges(); |
不同SubmitChanges 不会做事务处理
下例由于ItemID主键冲突,后一条数据都不会被插入
|
myContext context1 = new myContext(); DBItem item1 = new DBItem(); item1.ItemID = "w"; item1.ItemMatter = "wxwinter"; context1.AddObject("DBItem", item1); context1.SaveChanges(); myContext context2 = new myContext(); DBItem item2 = new DBItem(); item2.ItemID = "w"; item2.ItemMatter = "wxd"; context2.AddObject("DBItem", item2); context2.SaveChanges(); |
System.Data.Common.DbTransaction
下例由于ItemID主键冲突,两条数据都不会被插入
|
myContext context1 = new myContext(); DBItem item1 = new DBItem(); item1.ItemID = "w"; item1.ItemMatter = "wxwinter"; context1.AddObject("DBItem", item1); if (context1.Connection.State != ConnectionState.Open) { context1.Connection.Open(); } System.Data.Common.DbTransaction tran = context1.Connection.BeginTransaction(); context1.SaveChanges(); try { DBItem item2 = new DBItem(); item2.ItemID = "w"; item2.ItemMatter = "wxd"; context1.AddObject("DBItem", item2); context1.SaveChanges(); tran.Commit(); } catch { tran.Rollback(); } |
死锁(两个Context使用DbTransaction)
|
myContext context1 = new myContext(); DBItem item1 = new DBItem(); item1.ItemID = "w"; item1.ItemMatter = "wxwinter"; context1.AddObject("DBItem", item1); if (context1.Connection.State != ConnectionState.Open) { context1.Connection.Open(); } System.Data.Common.DbTransaction tran = context1.Connection.BeginTransaction(); context1.SaveChanges(); try { myContext context2 = new myContext(); DBItem item2 = new DBItem(); item2.ItemID = "w"; item2.ItemMatter = "wxd"; context2.AddObject("DBItem", item2); context2.SaveChanges(); tran.Commit(); } catch { tran.Rollback(); } |
TransactionScope 事务(两个Context)
System.Transactions.TransactionScope
可解决[死锁(两个Context使用DbTransaction)]
下例由于ItemID主键冲突,两条数据都不会被插入
|
using (System.Transactions.TransactionScope tc = new TransactionScope()) { try { myContext context1 = new myContext(); DBItem item1 = new DBItem(); item1.ItemID = "w"; item1.ItemMatter = "wxwinter"; context1.AddObject("DBItem", item1); context1.SaveChanges(); myContext context2 = new myContext(); DBItem item2 = new DBItem(); item2.ItemID = "w"; item2.ItemMatter = "wxd"; context2.AddObject("DBItem", item2); context2.SaveChanges(); tc.Complete(); } catch { } } |
ADO.NET Entity Framework学习笔记(3)ObjectContext的更多相关文章
- Entity Framework学习笔记
原文地址:http://www.cnblogs.com/frankofgdc/p/3600090.html Entity Framework学习笔记——错误汇总 之前的小项目做完了,到了总结经验和 ...
- Entity Framework 学习笔记(2)
上期回顾:Entity Framework 学习笔记(1) Entity Framework最主要的东西,就是自己创建的.继承于DbContext的类: /// <summary> /// ...
- Entity Framework学习笔记(二)----CRUD(1)
请注明转载地址:http://www.cnblogs.com/arhat 这篇文章老魏和大家分享一下Entity Framework的CRUD操作,在这之前呢,老魏先说一下老魏对EF的一个整体的认识, ...
- Entity Framework学习笔记——错误汇总
之前的小项目做完了,到了总结经验和更新学习笔记的时间了.开始正题之前先啰嗦一下,对之前的学习目标进行一个调整:“根据代码生成表”与“生成数据库脚本和变更脚本”合并为“Code First模式日常使用篇 ...
- Entity Framework学习笔记——记一个错误解决方式及思路
继续之前设定的学习目标前,先来一篇小小的外篇.按照第一篇里的配置方式配置好的工程前两天还能正常工作,昨天却突然无法通过Add-Migration命令进行数据库的升级.错误信息如下: System.Da ...
- Entity Framework学习笔记(三)----CRUD(2)
请注明转载地址:http://www.cnblogs.com/arhat 昨天晚上老魏配的机器终于到了,可是拿回来之后什么都组装好了,唯独差一个非常重要的组件"电源线",老魏那个汗 ...
- Entity Framework学习笔记(一)
请注明转载地址:http://www.cnblogs.com/arhat 哈哈!老魏回来了,4月份的内容开始更新了,由于3月份时间都在做项目,没有时间写了,那么4月份老魏会尽可能的多写点东西的.那么4 ...
- Entity Framework学习笔记——配置EF
初次使用Entity Framework(以下简称EF),为了避免很快忘记,决定开日志记录学习过程和遇到的问题.因为项目比较小,只会用到EF的一些基本功能,因此先在此处制定一个学习目标:1. 配置EF ...
- Entity Framework学习笔记(四)----Linq查询(1)
请注明转载地址:http://www.cnblogs.com/arhat 从本章开始,老魏就介绍一下Entity Framework使用Linq来查询数据,也就是Linq To Entity.其实在E ...
随机推荐
- STM32的FLASH ID加密
#define FLASH_ID_OFFSET 30000 //任意定义一个数 //把地址直接减去或者加上一个数是不要程序中直接出现这个地址 volatile u32 Flash_ID_addr ...
- HTTP协议和XMPP协议、MQTT协议
应用层协议:每个应用层的都是为了解决某一类应用问题.而问题的解决又必须通过位于不同主机中的多个应用进程之间的通信和协同工作来完成.应用进程之间必须遵守严格的规则.应用层协议应当定义如下几个: 应用进程 ...
- You have new mail in /var/spool/mail/root
centos7.5 查看邮件的方式: [root@web01 code]# yum -y install mailx #安装mailx [root@web01 code]# mail #执行mail命 ...
- 终于明白vim 和 grep 中 的正则表达式的用法, vim 正则表达式 和grep基本正则表达式 几乎一样
要搞清楚 vim中的正则和普通的Perl正则表达式的区别: 因为在perl中所有的元字符 都可以直接使用, 不需要在 元字符的前面加 反斜杠. 但是在vim, 包括grep中就有所区别, 同样是元字符 ...
- MySQL 日期时间函数
目录 datetime和timestamp区别: timestamp类型字段特殊性: Mysql获取日期时间函数: now() curdate() curtime() Extract() last_d ...
- JWT、OAUTH2与SSO资料补充
JWT: 阮一峰:http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html https://blog.csdn.net/q ...
- HDU 3401 Trade(斜率优化dp)
http://acm.hdu.edu.cn/showproblem.php?pid=3401 题意:有一个股市,现在有T天让你炒股,在第i天,买进股票的价格为APi,卖出股票的价格为BPi,同时最多买 ...
- HDU 6249 Alice’s Stamps(dp)
http://acm.hdu.edu.cn/showproblem.php?pid=6249 题意: 给出n个区间,求选k个区间的最大区间并. 思路: 可能存在左端点相同的多个区间,那么此时我们肯定选 ...
- JavaScript(ES5)知识点梳理
数据类型(null undefined number string boolean object)数据类型之间的相互转化(Boolean Number String parseInt parseFlo ...
- C#:CsvReader读取.CSV文件(转换成DataTable)
原文引用:https://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader using LumenWorks.Framework.IO.Csv; ...



