zoukankan      html  css  js  c++  java
  • 《Entity Framework 6 Recipes》中文翻译——第九章EntityFramework在N层架构程序中的应用(七)

    在WCF服务中的序列化代理

    问题

      您有一个从查询返回的动态代理对象,你想要把它像POCO对象已经进行序列化。在序列化基于实体对象的POCO(普通旧CLR对象)时,实体框架会自动生成一个动态生成的派生类型为每个POCO实体对象,称为动态代理对象。代理对象覆盖了许多的POCO类虚拟属性去注册钩子为展现功能,如更改跟踪和相关实体的延迟加载。

    解决方案

      假设你有如下一个模型

      我们将使用代理数据契约解析器反序列化一个代理对象为POCO对象在WCF客户端。执行以下操作:

      1、创建一个新的WCF服务应用程序。添加ADO.NET Entity Data Model,选择Client表

      2、打开实体框架生成的客户端POCO类,并添加虚拟关键字为每个属性,这样做会导致实体框架生成动态代理类。

    public class Client
    {
        public virtual int ClientId { get; set; }
        public virtual string Name { get; set; }
        public virtual string Email { get; set; }
    }

      我们需要的数据协定序列化程序使用代理数据契约解析类为WCF服务的客户端将客户端Client代理转换为Client实体。为此,我们将创建一个操作行为属性和应用属性到GetClient()服务方法。记住,代理数据契约解析类驻留在实体框架命名空间。

    public class ApplyProxyDataContractResolverAttribute : Attribute, IOperationBehavior
        {
            public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
            {
                
            }
    
            public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
            {
                DataContractSerializerOperationBehavior dataContractSerializerOperationBehavior =
                          operationDescription.Behaviors.Find <DataContractSerializerOperationBehavior>();
                dataContractSerializerOperationBehavior.DataContractResolver =
                          new ProxyDataContractResolver();
    
            }
    
            public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
            {
                DataContractSerializerOperationBehavior dataContractSerializerOperationBehavior =
                          operationDescription.Behaviors.Find<DataContractSerializerOperationBehavior>();
                dataContractSerializerOperationBehavior.DataContractResolver =
                           new ProxyDataContractResolver();
            }
    
            public void Validate(OperationDescription operationDescription)
            {
            }
        }

      4、修改Iservice.cs的代码如下

     [ServiceContract]
        public interface IService1
        {
            [OperationContract]
            void InsertTestRecord();
    
            [OperationContract]
            Client GetClient();
    
            [OperationContract]
            void Update(Client client);
        }

      5、实现Iservice中的接口在IService1.svc.cs 中

    public class Service1 : IService1
        {
            [ApplyProxyDataContractResolverAttribute]
            public Client GetClient()
            {
                using (var context = new EntitiesContext())
                {
                    context.Configuration.LazyLoadingEnabled = false;
                    return context.Clients.Single();
                }
    
            }
            [ApplyProxyDataContractResolverAttribute]
            public void InsertTestRecord()
            {
                using (var context = new EntitiesContext())
                {
                    context.Database.ExecuteSqlCommand("delete from Client");
                    context.Database.ExecuteSqlCommand(@"insert into
                          Client(Name, Email)
                          values ('Jerry Jones','jjones@gmail.com')");
    
                }
            }
            [ApplyProxyDataContractResolverAttribute]
            public void Update(Client client)
            {
                using (var context = new EntitiesContext())
                {
                    context.Entry(client).State =
                           EntityState.Modified;
                    context.SaveChanges();
                }
            }
        }

    6、在解决方案中添加一个新的控制台应用程序项目作为我们的客户端,同时添加WCF服务引用

    class Program
        {
            static void Main(string[] args)
            {
                using (var serviceClient = new Service1Client())
                {
                    serviceClient.InsertTestRecord();
                    var client = serviceClient.GetClient();
                    Console.WriteLine("Client is: {0} at {1}",
                                        client.Name, client.Email);
                    client.Name = "Alex Park";
                    client.Email = "Alex P@hotmail.com";
                    serviceClient.Update(client);
                    client = serviceClient.GetClient();
                    Console.WriteLine("Client changed to: {0} at {1}",
                                        client.Name, client.Email);
    
                }
            }
    }

    结果:

      微软建议使用WCF POCO对象简化实体对象的序列化。然而,如果你的应用程序是使用POCO对象改变的通知(你有虚拟和显著的性能导航属性集合的类型是ICollection),然后实体框架会创建查询返回的实体动态代理。

  • 相关阅读:
    SpringBoot之使用外部的启动类
    CCF——最小差值(2017-12)
    CCF——买菜(2018-09)
    CCF——卖菜(2018-09)
    2792. Grammar Lessons
    2756. Lucky Transformation
    2776. String Task
    2794. Petya and Strings
    2810. Palindromic Times
    14. Football
  • 原文地址:https://www.cnblogs.com/yunxiaguo/p/5704620.html
Copyright © 2011-2022 走看看