zoukankan      html  css  js  c++  java
  • 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

    {

    }

    }

  • 相关阅读:
    494 Target Sum 目标和
    493 Reverse Pairs 翻转对
    492 Construct the Rectangle 构建矩形
    491 Increasing Subsequences 递增子序列
    488 Zuma Game 祖玛游戏
    486 Predict the Winner 预测赢家
    485 Max Consecutive Ones 最大连续1的个数
    483 Smallest Good Base
    Django Form组件
    Django Auth组件
  • 原文地址:https://www.cnblogs.com/ejiyuan/p/1490786.html
Copyright © 2011-2022 走看看