程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> VS 2008 sp1 + .NET 3.5 sp1(5)

VS 2008 sp1 + .NET 3.5 sp1(5)

編輯:關於.NET

Entity Framework(實體框架)之ObjectContext

介紹

以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();
  }
}
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved