再接再厉VS 2008 sp1 + .NET 3.5 sp1(5) - Entity Framework(实体框架)之ObjectContext

[索引页]
[源码下载]


再接再厉VS 2008 sp1 + .NET 3.5 sp1(5) - Entity Framework(实体框架)之ObjectContext


作者: webabcd


介绍
以Northwind为示例数据库,ADO.NET Entity Framework之详解ObjectContext, 以及事务和并发
  • ObjectContext - 以对象(这些对象是 EDM 中定义的实体类型的实例)的形式与数据进行交互
  • CreateObjectName - 实体类 的 CreateObjectName 静态方法用于创建实体类的新实例
  • AddToEntitySetName() - 将需要添加的对象添加到对象上下文中
  • SaveChanges() - 将所有更新保存到相关存储区中
  • Attach()/AttachTo() - 附加外部实体到上下文中
  • ObjectContext.Refresh() - 更新上下文数据
  • ObjectStateEntry - 维护实体状态的类
  • ObjectStateManager - 实体状态管理器


示例
1、详解ObjectContext
ObjectContext.aspx
<%@ Page Title= "ObjectContext" Language= "C#" MasterPageFile= "~/Site.master" AutoEventWireup= "true" 
        CodeFile= "ObjectContext.aspx.cs"  Inherits= "EntityFramework_ObjectContext" %> 

<asp:Content ID= "Content1" ContentPlaceHolderID= "head" runat= "Server"
</asp:Content> 
<asp:Content ID= "Content2" ContentPlaceHolderID= "ContentPlaceHolder1" runat= "Server"
        <div id= "result" runat= "server" /> 
</asp:Content> 
 
ObjectContext.aspx.cs
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

using System.Data.Objects; 
using System.Data.Objects.DataClasses; 
using System.Data; 

using VS2008SP1.Business; 

public partial  class EntityFramework_ObjectContext : System.Web.UI.Page 

void Page_Load() void Page_Load(object sender, EventArgs e) 
        { 
                 if (!Page.IsPostBack) 
                { 
                        Demo(); 

                        result.InnerHtml +=  "<br />"

                        Demo2(); 

                        result.InnerHtml +=  "<br />"

                        Demo3(); 

                        result.InnerHtml +=  "<br />"

                        Demo4(); 

                        result.InnerHtml +=  "<br />"

                        Demo5(); 

                        result.InnerHtml +=  "<br />"

                        Demo6(); 
                } 
        } 

void Demo() void Demo() 
        { 
                // ObjectContext -    以对象(这些对象是 EDM 中定义的实体类型的实例)的形式与数据进行交互 
                using (var ctx =  new NorthwindEntities()) 
                { 
                        // CreateObjectName - 实体类 的 CreateObjectName 静态方法用于创建实体类的新实例 
                        Region region = Region.CreateRegion( "RegionDescription", 100); 

                        // System.Data.EntityState - 实体状态 
                        // System.Data.EntityState.Detached - 被分离 
                        // System.Data.EntityState.Unchanged - 未发生变化 
                        // System.Data.EntityState.Added - 被增加 
                        // System.Data.EntityState.Deleted - 被删除 
                        // System.Data.EntityState.Modified - 被修改 

                        result.InnerHtml += region.EntityState +  "<br />"; // Detached 
                        // AddToEntitySetName() - 将需要添加的对象添加到对象上下文中 
                        // AddObject( string entitySetName, object entity) - 将需要添加的对象添加到对象上下文中 
                        // ctx.AddObject( "Region", region); 
                        ctx.AddToRegion(region); 
                        result.InnerHtml += region.EntityState +  "<br />"; // Added 

                        // SaveChanges() - 将所有更新保存到相关存储区中。将所有实体的 EntityState 标记为 EntityState.Unchanged    
                        // SaveChanges(bool acceptChangesDuringSave) - acceptChangesDuringSave 指定是否将所有实体的 EntityState 标记为 EntityState.Unchanged 。 如果指定为  false 则不会修改实体的 EntityState 
                        ctx.SaveChanges(); 

                        result.InnerHtml += region.EntityState +  "<br />"; // Unchanged 
                } 
        } 

void Demo2() void Demo2() 
        { 
                using (var ctx =  new NorthwindEntities()) 
                { 
                        Region region = ctx.Region.First(p => p.RegionID == 100); 

                        result.InnerHtml += region.EntityState +  "<br />"; // Unchanged 
                        region.RegionDescription =  "RegionDescriptionUpdated"
                        result.InnerHtml += region.EntityState +  "<br />"; // Modified 

                        ctx.SaveChanges( false); 
                         
                        // ObjectStateEntry - 维护实体状态的类 
                        //         GetModifiedProperties() - 获取被修改的属性。返回值 IEnumerable< string>    
                        // ObjectStateManager - 实体状态管理器 
                        //         GetObjectStateEntry()/TryGetObjectStateEntry() - 获取指定实体的 ObjectStateEntry 
                        //         GetObjectStateEntries(EntityState state) - 获取所指定状态的 ObjectStateEntry 集合。返回值 IEnumerable<ObjectStateEntry> 
                        //         ObjectStateManagerChanged事件 - 将实体添加到 ObjectStateManager 中或从中移除实体时发生 
                        ObjectStateEntry ose = ctx.ObjectStateManager.GetObjectStateEntry(region); 

                        // ObjectStateEntry.State - 实体状态 
                        // ObjectStateEntry.OriginalValues - 原始值 
                        // ObjectStateEntry.CurrentValues - 当前值 
                        result.InnerHtml += ose.State +  "<br />"; // Modified (region.EntityState) 
                        result.InnerHtml += ose.OriginalValues[ "RegionDescription"] +  "<br />"; // RegionDescription 
                        result.InnerHtml += ose.CurrentValues[ "RegionDescription"] +  "<br />"; // RegionDescriptionUpdated 

                        // ObjectStateEntry.AcceptChanges()/ObjectContext.AcceptAllChanges() - 将相关的实体状态置为 EntityState.Unchanged 
                        ose.AcceptChanges(); 

                        result.InnerHtml += ose.State +  "<br />"; // Unchanged 
                } 
        } 

void Demo3() void Demo3() 
        { 
                using (var ctx =  new NorthwindEntities()) 
                { 
                        // 加载指定的 Region 到上下文中 
                        Region regionRead = ctx.Region.First(p => p.RegionID == 100); 
                        // 创建一个需要更新的 Region 
                        Region regionUpdate = Region.CreateRegion( "RegionDescriptionUpdatedSecond", 100); 

                        result.InnerHtml += regionRead.EntityState +  "<br />"; // Unchanged 
                        result.InnerHtml += regionUpdate.EntityState +  "<br />"; // Detached 
                        // ApplyPropertyChanges( string entitySetName, object changed) - 更新指定的实体(其所对应的主键实体需要加载到上下文中) 
                        ctx.ApplyPropertyChanges( "Region", regionUpdate); 
                        result.InnerHtml += regionRead.EntityState +  "<br />"; // Modified 
                        result.InnerHtml += regionUpdate.EntityState +  "<br />"; // Detached 

                        ctx.SaveChanges(); 
                } 
        } 

void Demo4() void Demo4() 
        { 
                using (var ctx =  new NorthwindEntities()) 
                { 
                        Region region =  new Region() { RegionID = 100, RegionDescription =  "RegionDescriptionUpdatedThird" }; 

                        result.InnerHtml += region.EntityState +  "<br />"; // Detached 

                        // Attach()/AttachTo() - 附加外部实体到上下文中 
                        // ctx.Attach(region); 
                        ctx.AttachTo( "Region", region); 

                        ObjectStateEntry ose = ctx.ObjectStateManager.GetObjectStateEntry(region); 

                        // SetModified() - 标记实体状态为 EntityState.Modified 
                        // SetModifiedProperty() - 标记需要修改的属性,从而完成对指定属性的修改 
                        ose.SetModifiedProperty( "RegionDescription"); 

                        // 以当前数据为准更新存储模型 
                        ctx.Refresh(RefreshMode.ClientWins, region);     

                        result.InnerHtml += region.EntityState +  "<br />"; // Modified 

                        ctx.SaveChanges(); 
                } 
        } 

void Demo5() void Demo5() 
        { 
                using (var ctx =  new NorthwindEntities()) 
                { 
                        Region region =  new Region() { RegionID = 100 }; 

                        // CreateEntityKey( string entitySetName, object entity) - 创建 EntityKey 
                        EntityKey ek = ctx.CreateEntityKey( "Region", region); 

                        // ObjectContext.GetObjectByKey()/TryGetObjectByKey() - 根据指定的 EntityKey 获取实体 
                        Region r = ctx.GetObjectByKey(ek)  as Region; 

                        ctx.SaveChanges(); 

                        result.InnerHtml += r.RegionDescription +  "<br />"; // RegionDescriptionUpdatedThird    
                } 
        } 

void Demo6() void Demo6() 
        { 
                using (var ctx =  new NorthwindEntities()) 
                { 
                        Region region = ctx.Region.First(p => p.RegionID == 100); 

                        result.InnerHtml += region.EntityState +  "<br />"; // Unchanged 

                        // ObjectStateEntry.Delete() - 标记实体的状态为删除。同 DeleteObject() 
                        ObjectStateEntry ose = ctx.ObjectStateManager.GetObjectStateEntry(region); 
                        ose.Delete(); 

                        // DeleteObject() - 删除实体 
                        // ctx.DeleteObject(region); 

                        result.InnerHtml += region.EntityState +  "<br />"; // Deleted 

                        ctx.SaveChanges(); 
                } 
        } 
}
 
 
2、事务和并发处理
ObjectContext2.aspx
<%@ Page Title= "事务和并发处理" Language= "C#" MasterPageFile= "~/Site.master" AutoEventWireup= "true" 
        CodeFile= "ObjectContext2.aspx.cs"  Inherits= "EntityFramework_ObjectContext2" %> 

<asp:Content ID= "Content1" ContentPlaceHolderID= "head" runat= "Server"
</asp:Content> 
<asp:Content ID= "Content2" ContentPlaceHolderID= "ContentPlaceHolder1" runat= "Server"
        <div id= "result" runat= "server" /> 
</asp:Content>

ObjectContext2.aspx.cs
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

using System.Data.Objects; 
using System.Data.Objects.DataClasses; 
using System.Data; 

using VS2008SP1.Business; 

public partial  class EntityFramework_ObjectContext2 : System.Web.UI.Page 

void Page_Load() void Page_Load(object sender, EventArgs e) 
        { 
                 if (!Page.IsPostBack) 
                { 
                        // 演示事务的 Demo 
                        Demo(); 

                        result.InnerHtml +=  "<br />"

                        // 演示并发的 Demo 
                        Demo2(); 
                } 
        } 

void Demo() void Demo() 
        { 
                // ObjectContext - SaveChanges 中的逻辑会自动做事务处理 

                // 通吃的事务处理 
                // using (System.Transactions.TransactionScope tc =  new TransactionScope()) 
                // { 
                //         code 
                //         tc.Complete();    
                // } 

                // 同一 ObjectContext 的多个 SaveChanges() 的事务处理 
                using (var ctx =  new NorthwindEntities()) 
                { 
                        Region region = Region.CreateRegion( "Test", 101); 
                        ctx.AddToRegion(region); 

                         if (ctx.Connection.State != ConnectionState.Open) 
                        { 
                                ctx.Connection.Open(); 
                        } 

                        // 开始一个事务 
                        System.Data.Common.DbTransaction tran = ctx.Connection.BeginTransaction(); 

                        // 第一次对数据的操作 
                        ctx.SaveChanges(); 

                        try 
                        { 
                                Region region2 = Region.CreateRegion( "Test2", 101); 
                                ctx.AddToRegion(region2); 
                                // 第二次对数据库的操作 
                                ctx.SaveChanges(); 

                                // 提交事务(第一次插入主键为 101 的记录,成功;第二次再次插入主键为 101 的记录,失败。所以此处会报错) 
                                tran.Commit(); 
                        } 
                        catch (Exception) 
                        { 
                                result.InnerHtml +=  "回滚" +  "<br />"

                                // 回滚事务(第一次插入成功的主键为 101 的记录会被删除) 
                                tran.Rollback(); 
                        } 
                } 
        } 

void Demo2() void Demo2() 
        { 
                var ctx =  new NorthwindEntities(); 
                var ctx2 =  new NorthwindEntities(); 

                var region = ctx.Region.First(); 
                var region2 = ctx2.Region.First(); 

                // 需要做并发处理的字段,要将其“并发模式”属性设置为 Fixed 
                region.RegionDescription =  "Eastern" + Guid.NewGuid().ToString(); 
                region2.RegionDescription =  "Eastern" + Guid.NewGuid().ToString(); 

                ctx.SaveChanges(); 

                try 
                { 
                        // ctx 已经修改了 Region 的 RegionDescription 属性 
                        // ctx2 再次修改 Region 的 RegionDescription 属性,由于 RegionDescription 在 ctx2 读取之后发生了变化,所以会出现乐观并发(Optimistic Concurrency)问题 
                        ctx2.SaveChanges(); 
                } 
                catch (System.Data.OptimisticConcurrencyException) 
                { 
                        result.InnerHtml +=  "OptimisticConcurrencyException" +  "<br />"

                        // ObjectContext.Refresh(RefreshMode refreshMode, object entity) - 更新上下文数据 
                        //         RefreshMode.StoreWins - 以数据库中的值为准 
                        //         RefreshMode.ClientWins - 以当前数据为准 
                        //         object entity - 需要刷新上下文数据的实体 
                        ctx2.Refresh(RefreshMode.StoreWins, region2); 
                        // ctx2.Refresh(RefreshMode.ClientWins, region2); 

                        ctx2.SaveChanges(); 
                } 

                // 可以不通过 try catch 处理并发,而是通过 Refresh() 直接处理更新逻辑 
                // 即若是 RefreshMode.ClientWins 则永远以当前值为准;若是 RefreshMode.StoreWins 则永远以数据库中的值为准(不会更新数据) 
                // ctx2.Refresh(RefreshMode.StoreWins, region2); 
                // ctx2.SaveChanges(); 

                ctx.Dispose(); 
                ctx2.Dispose(); 
        } 
}
 
 



     本文转自webabcd 51CTO博客,原文链接:http://blog.51cto.com/webabcd/341466 ,如需转载请自行联系原作者


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值