• 再接再厉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
    {
        
    protected 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();
            }

        }


        
    private 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
            }

        }


        
    private 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
            }

        }


        
    private 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();
            }

        }


        
    private 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();
            }

        }


        
    private 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 
            }

        }


        
    private 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
    {
        
    protected void Page_Load(object sender, EventArgs e)
        
    {
            
    if (!Page.IsPostBack)
            
    {
                
    // 演示事务的 Demo
                Demo();

                result.InnerHtml 
    += "<br />";

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

        }


        
    private 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();
                }

            }

        }


        
    private 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();
        }

    }


    OK
    [源码下载]
  • 相关阅读:
    【成本管理】成本核算
    CW23:Work Log
    SQLSERVER数据库连接
    Oracle 创建用户 修改用户密码 授权命令
    CW24:WORK LOG
    ORA12560: TNS: 协议适配器错误的解决方法
    需求工程概述
    日语学习1:送气音和不送气音
    junit测试框架简单应用
    Java之Socket编程
  • 原文地址:https://www.cnblogs.com/webabcd/p/1386589.html
Copyright © 2020-2023  润新知