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集合内的[实体]同步.

  1. ApplyPropertyChanges调用时,要求对应的[实体]在内存中,Attach不要求
  2. ApplyPropertyChanges调用后,集合内的实体状态会标记为EntityState.Modified
    Attach调用后不会修改合内的实体状态,如要SaveChanges(),要手动标记EntityState.Modified
  3. 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 根据实体对象或实体主键得到状态实体

实体必须在当前连接对象 context 中否则无法获取实体状态会引发:
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);
    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

{

}

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值