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
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,可以使用不在集合中的实体覆盖到集合中主键对应用实体上
如果内存中没有主键对应的记录,会报错
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();
Attach / AttachTo 附加实体使用Attach方法可将[外部实体]附加到Context集合中
在使用 服务器/客户端模式,或要将[实体]从Context集合中分离,修改后要用Context更新回数据库时,可用这种方式
Attach与ApplyPropertyChanges有类似之处,都是将Context集合外的[实体]与Context集合内的[实体]同步.
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 创建EntityKeymyContext context = new myContext();
myTab nr = myTab.CreatemyTab(1);
EntityKey ek= context.CreateEntityKey("myTab", nr);
EntityKeyEntityContainerName 属性
?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]
后修改