说明
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; |
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(); |
修改前
修改后
|
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); 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 根据实体对象或实体主键得到状态实体
ObjectStateManager 不包含具有对“ context ”类型的对象的引用的 ObjectStateEntry
也就是该方法无法获取已分离的实体对象状态
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); 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); 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); //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); context.AcceptAllChanges(); 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); |
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 { } } |