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

  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

{

}

}

时间: 2024-10-13 07:25:07

ADO.NET Entity Framework学习笔记(3)ObjectContext的相关文章

Entity Framework 学习笔记(2)

上期回顾:Entity Framework 学习笔记(1) Entity Framework最主要的东西,就是自己创建的.继承于DbContext的类: /// <summary> /// Context相当于一个数据库 /// </summary> public class MusicContext : DbContext { //base("LocalDB")表示要用到config文件中的名为"LcoalDB"的连接字符串 public

Entity Framework学习笔记——edmx文件

上文简单介绍了一下Entity FrameWork,这里说一下EF的核心--edmx文件. 在VisualStudio中建立edmx文件(此例环境为VisualStudio2012) 1.新建-ADO.NET实体数据模型: 2.选择数据模型时,因为我之前已经在数据库中建立好表了,所以我们这里先选择从数据库生成(即DB First),如果选择空模型,就可以在没有建立数据库的情况下,通过先建立实体模型来生成实体类和数据库表. 3.选择数据库连接 4.选择或设置好连接的服务器.验证信息.数据库名: 5

Entity Framework 学习笔记(二)之数据模型 Model 使用过程

欢迎大家加入我们:ASP.NET交流群(1群) ExtJs4.2交流群(3群) 97869295 Entity Framework  数据模型 Model 创建的使用: 开发环境:VS2012 数据库:SQL Server 2008 Entity Framework  版本:6.12 下面是新建的项目架构:(当然这是我的项目架构,只是参考) 1. 新建项目 新建一个控制台项目即可 :Future.LifeWillBetter.DAL.ForModel.ConsoleApplication 如图:

Entity Framework学习笔记——EF简介(一篇文章告诉你什么是EF)

Entity Framework是以ADO.NET为基础,面向数据的"实体框架".以下简称EF. 它利用了抽象化数据结构的方式,将每个数据库对象都转换成应用程序对象 (entity),数据字段都转换为属性 (property),关系则转换为结合属性 (association),让数据库的 E/R 模型完全的转成对象模型,如此让程序设计师能用最熟悉的编程语言来调用访问. 个人认为百科上对EF一句比较经典的解释为:让上层的应用程序码可以如面向对象的方式般访问数据. 过去我们对数据库都是直接

Entity Framework 学习笔记(1)

from:http://www.cnblogs.com/Richeir/p/5347000.html 开始从头系统地学习Entity Framework,当前的稳定版本为6.1.3,Nuget主页 http://www.nuget.org/packages/EntityFramework/ 微软喜欢把Entity Framework和ASP.NET MVC放在一起来用,从Entity Framework的主页的所有者就可以看出来 当然,这两者也是紧密的结合在一起的,“新一代”Web开发框架和“新

Entity Framework 学习笔记(一)之数据模型 数据库

关于Entity Framework  数据模型 的开发有三种模式:1.引用数据库方式:2.在VS中新建EF空模型Model 方式:3.Code 方式 Entity Framework  数据模型  引用"引用数据库方式"进行开发创建的使用,具体如下: 开发环境:VS2012 数据库:SQL Server 2008 Entity Framework  版本:6.12 1.新建数据库 在数据库中新建数据库,并创建数据表,以下截图只供参考: 2.新建项目 在VS中新建一个控制台应用程序 F

Entity Framework 学习笔记

1.自定义数据库链接字符串上下文 public class PetDbContext : DbContext { public PetDbContext() : base("name=DemoDB") { } public DbSet<Dog> Dogs { get; set; } } 2.Code First 模型迁移相关命令 Enable-Migrations 启用模型迁移,会自动建立Migrations文件夹,里面记录模型修改历史 Add-Migration AddT

【.NET-EF】Entity Framework 学习笔记5:懒人的Linqer

真的没有做不到,只有你想不到,当苦恼Linq写法很别扭,一点不像SQL(写SQL写习惯了),就想到有没一个工具可以把SQL语句转成Linq语句,然后就搜到了这个工具:Linqer. 很简单的工具(越简单越好),网上搜索下一下,打开来(有些要安装,我这个不用),连下数据库,再点Generate to LinQ找个地方给它放,就可以开始是使用. 对于刚刚学习,和转不过弯的我有很好的帮助.(谢谢作者大神)

【.NET-EF】Entity Framework 学习笔记4:优点和缺点

EF,简单说将数据库的表生成实体类,每个结果都是实体类集(类型如IList<>,IQueryable<>),增删改查方法封装好了,直接操作,节省了去数据库工具写语句. EF5.0后有了延时执行,其实就是IQueryable<>和SaveChange(),意思就是你大可以将语句分几段写,最后才一次生成. EF是ORM框架(对象关系映射)的,在之前写的程序,我也经常自己去把数据库的表生成个实体类,方便开发,这框架更方便,封装好增删改查. 基于ADO.NET,会自动生成SQL