精进不休 .NET 4.0 (8) - ADO.NET Entity Framework 4.0 Self Tracking Entity

[索引页]
[源码下载]


精进不休 .NET 4.0 (8) - ADO.NET Entity Framework 4.0 Self Tracking Entity


作者:webabcd


介绍
ADO.NET Entity Framework 4.0 的新增功能
  • 对 Self Tracking Entity(实体状态自跟踪)的支持,基于 POCO 
  • WCF 结合 Self Tracking Entity 的应用 


示例
1、Self Tracking Entity 的 Demo
SelfTrackingDemo/BLL.cs
代码
/*
 * ADO.NET Entity Framework 4.0 - 对 Self Tracking Entity(实体状态自跟踪)的支持,基于 POCO
 *     1、不通过 WCF 使用 Self Tracking Entity 需要手动调用 StartTracking()
 *     2、MarkAsAdded(), MarkAsModified(), MarkAsDeleted() 会自动 StartTracking()
 *     3、ApplyChanges() 的作用是:绑定实体到上下文,通过 ChangeObjectState 改变实体的状态,通过 ChangeRelationshipState 改变关联实体的状态
 * 
 * 本 Demo 演示如何通过 Self Tracking Entity 来实现对单表的增删改查
 *     如果涉及到关联实体,可以参考 
http://www.cnblogs.com/webabcd/archive/2010/06/17/1759314.html 中的“对外键的支持”的 Demo
 
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SelfTrackingDemo
{
    
public class BLL
    {
        
// 取全部产品类别的实体集合
        public List<ProductCategory> GetCategories()
        {
            
using (SelfTrackingEntities ctx = new SelfTrackingEntities())
            {
                var result 
= ctx.ProductCategories.ToList();
                
return result;
            }
        }

        
// 根据 id 取产品类别实体
        public ProductCategory GetCategory(int categoryId)
        {
            
using (SelfTrackingEntities ctx = new SelfTrackingEntities())
            {
                var result 
= ctx.ProductCategories.Single(c => c.ProductCategoryID == categoryId);
                
return result;
            }
        }

        
// 根据产品类别实体更新数据库中的相关数据
        public void UpdateCategory(ProductCategory category)
        {
            
using (SelfTrackingEntities ctx = new SelfTrackingEntities())
            {
                
// ApplyChanges() 的内部逻辑为:绑定实体到上下文,通过 ChangeObjectState 改变实体的状态,通过 ChangeRelationshipState 改变关联实体的状态
                ctx.ProductCategories.ApplyChanges(category);

                
// 根据实体的状态,实现对实体的 添加、更新、删除 操作
                var affectedRow = ctx.SaveChanges();
            }
        }

        
// 根据产品类别实体删除数据库中的相关数据
        public void DeleteCategory(ProductCategory category)
        {
            
// 标记该实体为删除状态
            category.MarkAsDeleted();

            UpdateCategory(category);
        }

        
// 根据产品类别实体向数据库添加新的数据
        public void AddCategory(ProductCategory category)
        {
            UpdateCategory(category); 
        }
    }
}

SelfTrackingDemo/Demo.aspx
代码
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Demo.aspx.cs" Inherits="SelfTrackingDemo.Demo" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    
<title></title>
</head>
<body>
    
<form id="form1" runat="server">
    
<div>
        
<asp:ListView ID="ListView1" runat="server" DataSourceID="ObjectDataSource1" DataKeyNames="ProductCategoryID"
            InsertItemPosition
="LastItem" OnItemUpdating="ListView1_ItemUpdating">
            
<EditItemTemplate>
                
<tr style="">
                    
<td>
                        
<asp:Button ID="UpdateButton" runat="server" CommandName="Update" Text="Update" />
                        
<asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="Cancel" />
                    
</td>
                    
<td>
                        
&nbsp;
                    
</td>
                    
<td>
                        
&nbsp;
                    
</td>
                    
<td>
                        
<asp:TextBox ID="NameTextBox" runat="server" Text='<%# Bind("Name") %>' />
                    
</td>
                    
<td>
                        
&nbsp;
                    
</td>
                    
<td>
                        
&nbsp;
                    
</td>
                
</tr>
            
</EditItemTemplate>
            
<InsertItemTemplate>
                
<tr style="">
                    
<td>
                        
<asp:Button ID="InsertButton" runat="server" CommandName="Insert" Text="Insert" />
                        
<asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="Clear" />
                    
</td>
                    
<td>
                        
&nbsp;
                    
</td>
                    
<td>
                        
&nbsp;
                    
</td>
                    
<td>
                        
<asp:TextBox ID="NameTextBox" runat="server" Text='<%# Bind("Name") %>' />
                    
</td>
                    
<td>
                        
&nbsp;
                    
</td>
                    
<td>
                        
&nbsp;
                    
</td>
                
</tr>
            
</InsertItemTemplate>
            
<ItemTemplate>
                
<tr style="">
                    
<td>
                        
<asp:Button ID="DeleteButton" runat="server" CommandName="Delete" Text="Delete" />
                        
<asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="Edit" />
                    
</td>
                    
<td>
                        
<asp:Label ID="ProductCategoryIDLabel" runat="server" Text='<%# Eval("ProductCategoryID") %>' />
                    
</td>
                    
<td>
                        
<asp:Label ID="ParentProductCategoryIDLabel" runat="server" Text='<%# Eval("ParentProductCategoryID") %>' />
                    
</td>
                    
<td>
                        
<asp:Label ID="NameLabel" runat="server" Text='<%# Eval("Name") %>' />
                    
</td>
                    
<td>
                        
<asp:Label ID="rowguidLabel" runat="server" Text='<%# Eval("rowguid") %>' />
                    
</td>
                    
<td>
                        
<asp:Label ID="ModifiedDateLabel" runat="server" Text='<%# Eval("ModifiedDate") %>' />
                    
</td>
                
</tr>
            
</ItemTemplate>
            
<LayoutTemplate>
                
<table id="itemPlaceholderContainer" runat="server" border="0" style="">
                    
<tr runat="server" style="">
                        
<th runat="server">
                        
</th>
                        
<th runat="server">
                            ProductCategoryID
                        
</th>
                        
<th runat="server">
                            ParentProductCategoryID
                        
</th>
                        
<th runat="server">
                            Name
                        
</th>
                        
<th runat="server">
                            rowguid
                        
</th>
                        
<th runat="server">
                            ModifiedDate
                        
</th>
                    
</tr>
                    
<tr id="itemPlaceholder" runat="server">
                    
</tr>
                
</table>
            
</LayoutTemplate>
        
</asp:ListView>
        
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DataObjectTypeName="SelfTrackingDemo.ProductCategory"
            DeleteMethod
="DeleteCategory" InsertMethod="AddCategory" SelectMethod="GetCategories"
            TypeName
="SelfTrackingDemo.BLL" OnInserting="ObjectDataSource1_Inserting" OnDeleting="ObjectDataSource1_Deleting">
        
</asp:ObjectDataSource>
    
</div>
    
</form>
</body>
</html>

SelfTrackingDemo/Demo.aspx.cs
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace SelfTrackingDemo
{
    
public partial class Demo : System.Web.UI.Page
    {
        
protected void Page_Load(object sender, EventArgs e)
        {
            
        }

        
protected void ObjectDataSource1_Inserting(object sender, ObjectDataSourceMethodEventArgs e)
        {
            var category 
= e.InputParameters[0as ProductCategory;
            category.rowguid 
= Guid.NewGuid();
            category.ModifiedDate 
= DateTime.Now;
        }

        
protected void ObjectDataSource1_Deleting(object sender, ObjectDataSourceMethodEventArgs e)
        {
            
        }

        
protected void ListView1_ItemUpdating(object sender, ListViewUpdateEventArgs e)
        {
            BLL bll 
= new BLL();
            var category 
= bll.GetCategory((int)ListView1.DataKeys[e.ItemIndex].Value);

            
// 注意:这里一定要手动调用 StartTracking() 方法,用于跟踪实体状态的改变
            category.StartTracking();

            category.Name 
= e.NewValues["Name"].ToString();
            bll.UpdateCategory(category);

            ListView1.EditIndex 
= -1;
            e.Cancel 
= true;
        }
    }
}


2、WCF 结合 Self Tracking Entity 的 Demo
服务端:NTierServer/IMyService.cs
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace NTierServer
{
    [ServiceContract]
    
public interface IMyService
    {
        [OperationContract]
        List
<ProductCategory> GetCategories();

        [OperationContract]
        ProductCategory GetCategory(
int categoryId);

        [OperationContract]
        
int UpdateCategory(ProductCategory category);

        [OperationContract]
        
int AddCategory(ProductCategory category);

        [OperationContract]
        
int DeleteCategory(int categoryId);
    }
}

服务端:NTierServer/MyService.cs
代码
/*
 * ADO.NET Entity Framework 4.0 - WCF 结合 Self Tracking Entity 的应用
 *     1、通过 WCF 使用 Self Tracking Entity 不需手动调用 StartTracking()
 *     2、先 MarkAsAdded(), MarkAsModified(), MarkAsDeleted() 再 ApplyChanges() ; 或者 先 ApplyChanges() 再 ChangeObjectState(), ChangeRelationshipState()
 * 
 * 本 Demo 演示如何通过 WCF 结合 Self Tracking Entity 来实现对单表的增删改查
 
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Data;

namespace NTierServer
{
    
public class MyService : IMyService
    {
        
// 取全部产品类别的实体集合
        public List<ProductCategory> GetCategories()
        {
            
using (var ctx = new AdventureWorksEntities())
            {
                var result 
= ctx.ProductCategories.ToList();
                
return result;
            }
        }

        
// 根据 id 取产品类别实体
        public ProductCategory GetCategory(int categoryId)
        {
            
using (var ctx = new AdventureWorksEntities())
            {
                var result 
= ctx.ProductCategories.Single(c => c.ProductCategoryID == categoryId);
                
return result;
            }
        }

        
// 根据产品类别实体更新数据库中的相关数据
        public int UpdateCategory(ProductCategory category)
        {
            
using (var ctx = new AdventureWorksEntities())
            {
                
// 先 ApplyChanges() 再 ChangeObjectState(), ChangeRelationshipState()
                ctx.ProductCategories.ApplyChanges(category);
                ctx.ObjectStateManager.ChangeObjectState(category, EntityState.Modified);

                
return ctx.SaveChanges();
            }
        }

        
// 根据产品类别实体向数据库添加新的数据
        public int AddCategory(ProductCategory category)
        {
            
using (var ctx = new AdventureWorksEntities())
            {
                ctx.ProductCategories.ApplyChanges(category);
                
return ctx.SaveChanges();
            }
        }

        
// 根据 id 删除数据库中的相关数据
        public int DeleteCategory(int categoryId)
        {
            
using (var ctx = new AdventureWorksEntities())
            {
                var category 
= GetCategory(categoryId);

                
// 先 MarkAsAdded(), MarkAsModified(), MarkAsDeleted() 再 ApplyChanges()
                category.MarkAsDeleted();
                ctx.ProductCategories.ApplyChanges(category);

                
return ctx.SaveChanges();
            }
        }
    }
}

服务端:NTierServer/Web.config
代码
<system.serviceModel>
    
<behaviors>
        
<serviceBehaviors>
            
<behavior name="">
                
<serviceMetadata httpGetEnabled="true" />
                
<serviceDebug includeExceptionDetailInFaults="true" />
            
</behavior>
        
</serviceBehaviors>
    
</behaviors>
    
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>

客户端:NTierClient/Web.config
代码
<system.serviceModel>
    
<bindings>
        
<basicHttpBinding>
            
<binding name="BasicHttpBinding_IMyService" closeTimeout="00:01:00"
                openTimeout
="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                allowCookies
="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                maxBufferSize
="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding
="Text" textEncoding="utf-8" transferMode="Buffered"
                useDefaultWebProxy
="true">
                
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead
="4096" maxNameTableCharCount="16384" />
                
<security mode="None">
                    
<transport clientCredentialType="None" proxyCredentialType="None"
                        realm
="" />
                    
<message clientCredentialType="UserName" algorithmSuite="Default" />
                
</security>
            
</binding>
        
</basicHttpBinding>
    
</bindings>
    
<client>
        
<endpoint address="http://localhost:10394/MyService.svc" binding="basicHttpBinding"
            bindingConfiguration
="BasicHttpBinding_IMyService" contract="MyServiceReference.IMyService"
            name
="BasicHttpBinding_IMyService" />
    
</client>
</system.serviceModel>

客户端:NTierClient/Demo.aspx
代码
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Demo.aspx.cs" Inherits="NTierClient.Demo" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    
<title></title>
</head>
<body>
    
<form id="form1" runat="server">
    
<div>
        
<asp:ListView ID="ListView1" runat="server" DataKeyNames="ProductCategoryID" InsertItemPosition="LastItem"
            OnItemDeleting
="ListView1_ItemDeleting" OnItemInserting="ListView1_ItemInserting"
            OnItemUpdating
="ListView1_ItemUpdating" OnItemCanceling="ListView1_ItemCanceling"
            OnItemEditing
="ListView1_ItemEditing">
            
<EditItemTemplate>
                
<tr style="">
                    
<td>
                        
<asp:Button ID="UpdateButton" runat="server" CommandName="Update" Text="Update" />
                        
<asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="Cancel" />
                    
</td>
                    
<td>
                        
&nbsp;
                    
</td>
                    
<td>
                        
&nbsp;
                    
</td>
                    
<td>
                        
<asp:TextBox ID="NameTextBox" runat="server" Text='<%# Bind("Name") %>' />
                    
</td>
                    
<td>
                        
&nbsp;
                    
</td>
                    
<td>
                        
&nbsp;
                    
</td>
                
</tr>
            
</EditItemTemplate>
            
<InsertItemTemplate>
                
<tr style="">
                    
<td>
                        
<asp:Button ID="InsertButton" runat="server" CommandName="Insert" Text="Insert" />
                        
<asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="Clear" />
                    
</td>
                    
<td>
                        
&nbsp;
                    
</td>
                    
<td>
                        
&nbsp;
                    
</td>
                    
<td>
                        
<asp:TextBox ID="NameTextBox" runat="server" Text='<%# Bind("Name") %>' />
                    
</td>
                    
<td>
                        
&nbsp;
                    
</td>
                    
<td>
                        
&nbsp;
                    
</td>
                
</tr>
            
</InsertItemTemplate>
            
<ItemTemplate>
                
<tr style="">
                    
<td>
                        
<asp:Button ID="DeleteButton" runat="server" CommandName="Delete" Text="Delete" />
                        
<asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="Edit" />
                    
</td>
                    
<td>
                        
<asp:Label ID="ProductCategoryIDLabel" runat="server" Text='<%# Eval("ProductCategoryID") %>' />
                    
</td>
                    
<td>
                        
<asp:Label ID="ParentProductCategoryIDLabel" runat="server" Text='<%# Eval("ParentProductCategoryID") %>' />
                    
</td>
                    
<td>
                        
<asp:Label ID="NameLabel" runat="server" Text='<%# Eval("Name") %>' />
                    
</td>
                    
<td>
                        
<asp:Label ID="rowguidLabel" runat="server" Text='<%# Eval("rowguid") %>' />
                    
</td>
                    
<td>
                        
<asp:Label ID="ModifiedDateLabel" runat="server" Text='<%# Eval("ModifiedDate") %>' />
                    
</td>
                
</tr>
            
</ItemTemplate>
            
<LayoutTemplate>
                
<table id="itemPlaceholderContainer" runat="server" border="0" style="">
                    
<tr runat="server" style="">
                        
<th runat="server">
                        
</th>
                        
<th runat="server">
                            ProductCategoryID
                        
</th>
                        
<th runat="server">
                            ParentProductCategoryID
                        
</th>
                        
<th runat="server">
                            Name
                        
</th>
                        
<th runat="server">
                            rowguid
                        
</th>
                        
<th runat="server">
                            ModifiedDate
                        
</th>
                    
</tr>
                    
<tr id="itemPlaceholder" runat="server">
                    
</tr>
                
</table>
            
</LayoutTemplate>
        
</asp:ListView>
    
</div>
    
</form>
</body>
</html>

客户端:NTierClient/Demo.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.ServiceModel;

namespace NTierClient
{
    
public partial class Demo : System.Web.UI.Page
    {
        
protected void Page_Load(object sender, EventArgs e)
        {
            
if (!Page.IsPostBack)
            {
                BindData();
            }
        }

        
private void BindData()
        {
            var svc 
= new ChannelFactory<MyServiceReference.IMyService>("BasicHttpBinding_IMyService").CreateChannel();

            var categories 
= svc.GetCategories();
            ListView1.DataSource 
= categories;
            ListView1.DataBind();
        }

        
protected void ListView1_ItemUpdating(object sender, ListViewUpdateEventArgs e)
        {
            var svc 
= new MyServiceReference.MyServiceClient();
            var category 
= svc.GetCategory((int)ListView1.DataKeys[e.ItemIndex].Value);

            category.Name 
= (string)e.NewValues["Name"];

            svc.UpdateCategory(category);

            ListView1.EditIndex 
= -1;
            BindData();
        }

        
protected void ListView1_ItemInserting(object sender, ListViewInsertEventArgs e)
        {
            var category 
= new MyServiceReference.ProductCategory();
            category.Name 
= (string)e.Values["Name"];
            category.rowguid 
= Guid.NewGuid();
            category.ModifiedDate 
= DateTime.Now;

            var svc 
= new MyServiceReference.MyServiceClient();
            svc.AddCategory(category);

            BindData();
        }

        
protected void ListView1_ItemDeleting(object sender, ListViewDeleteEventArgs e)
        {
            var svc 
= new MyServiceReference.MyServiceClient();
            svc.DeleteCategory((
int)ListView1.DataKeys[e.ItemIndex].Value);

            BindData();
        }

        
protected void ListView1_ItemCanceling(object sender, ListViewCancelEventArgs e)
        {
            ListView1.EditIndex 
= -1;
            BindData();
        }

        
protected void ListView1_ItemEditing(object sender, ListViewEditEventArgs e)
        {
            ListView1.EditIndex 
= e.NewEditIndex;
            BindData();
        }
    }
}


OK
[源码下载]
posted @ 2010-06-21 09:10  webabcd  阅读(5925)  评论(9编辑  收藏  举报