• Wcf+EF框架搭建实例


    一.最近在使用Wcf创建数据服务,但是在和EF框架搭建数据访问时遇到了许多问题

    下面是目前整理的基本框架代码,经供参考使用,源代码地址:http://git.oschina.net/tiama3798/Wcf_EFDemo

    说明:框架搭建中使用EF访问数据库,简单工厂模式组织代码

    WCFThree.Entity:简单工厂模式的实体层、EF的实体模板、WCF的数据契约
    WCFThree.Abstract:简单工厂模式的抽象接口层、WCF服务操作契约
    WCFThree.Factory:简单工厂模式的实现层、WCF服务器契约实现
    WCFThree.Proxy:WCF的客户端代理封装
    WCFThree.Service:WCF的服务端定义
    WCFThree.Test:测试程序

    部分代码说明:

    1.为了使客户端和服务端使用相同的代理类,EF框架中禁用动态代理类实例,同时延迟加载也失效

            public BaseContext()
                : base("name=BaseContext")
            {
                //在Wcf中禁用EF的代理类和延迟加载
                this.Configuration.ProxyCreationEnabled = false;
            }

    2.为了解决序列化的循环引用问题,显示指定数据契约以及对应的属性,这样还有一个好处就是从服务端向客户端数据输出可以带着关联表数据(因为没法延迟加载,所以在服务器端需要再查询一次关联表数据)

        [Table("student")]
        [DataContract(IsReference = true)]
        public partial class student
        {
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
            public student()
            {
                scores = new HashSet<score>();
            }
    
            [Key]
            [StringLength(3)]
            [DataMember]
            public string sno { get; set; }
    
            [Required]
            [StringLength(100)]
            [DataMember]
            public string sname { get; set; }
    
            [StringLength(2)]
            [DataMember]
            public string ssex { get; set; }
    
            public DateTime? sbirthday { get; set; }
    
            [Column("class")]
            [StringLength(5)]
            [DataMember]
            public string _class { get; set; }
    
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
            [DataMember]
            public virtual ICollection<score> scores { get; set; }
        }

    3.客户端代理使用BasicHttpBinding创建

        public class RemoteServiceFactory
        {
            private string GetUrl(string Operate)
            {
                return string.Format("http://localhost:8733/Design_Time_Addresses/WCFThree.Service/{0}/", Operate);
            }
            /// <summary>
            /// 获取学生操作
            /// </summary>
            /// <returns></returns>
            public IStudent GetStudent()
            {
                string url = GetUrl("Student");
                return CreateService<IStudent>(url);
            }
            public IScore GetScore()
            {
                return CreateService<IScore>(GetUrl("Score"));
            }
            public IUserInfo GetUserInfo()
            {
                return CreateService<IUserInfo>(GetUrl("UserInfo"));
            }
            private T CreateService<T>(string url)
            {
                var binding = new BasicHttpBinding();
                binding.MaxReceivedMessageSize = maxReceivedMessageSize;
                binding.ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas();
                binding.ReaderQuotas.MaxStringContentLength = maxReceivedMessageSize;
                binding.ReaderQuotas.MaxArrayLength = maxReceivedMessageSize;
                binding.ReaderQuotas.MaxBytesPerRead = maxReceivedMessageSize;
    
                ChannelFactory<T> chan = new ChannelFactory<T>(binding, new EndpointAddress(url));
                //异常处理注册
                //cha.Endpoint.EndpointBehaviors.Add();
                foreach (var op in chan.Endpoint.Contract.Operations)
                {
                    var dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>() as DataContractSerializerOperationBehavior;
                    // 获取或设置对象图中要序列化或反序列化的最大项数。
                    if (dataContractBehavior != null)
                        dataContractBehavior.MaxItemsInObjectGraph = int.MaxValue;
                }
                chan.Open();
                return chan.CreateChannel();
            }
            private const int maxReceivedMessageSize = 2147483647;
        }

    4.测试及结果说明

        RemoteServiceFactory _remote = new RemoteServiceFactory();
        IStudent _IStudent = _remote.GetStudent();
    
        ////1.添加学生
        WCFThree.Entity.student stu1 = new Entity.student()
        {
            sno = "110",
            sname = "李四",
            ssex = "",
            sbirthday = DateTime.Now,
            _class = "95033"
        };
        _IStudent.Add(stu1);
    
        ////2.获取列表
        List<WCFThree.Entity.student> stuList = _IStudent.GetList();
        foreach (var item in stuList)
        {
            //编号-姓名---学习的课程数量(获取关联表数据失效)
            Console.WriteLine(string.Format("{0}-{1}--{2}", item.sno, item.sname, item.scores.Count));
        }
    
        //3.获取指定对象及关联数据----方式1:独立请求
        WCFThree.Entity.student stu2 = _IStudent.GetModel("101");
        Console.WriteLine(stu2.sname);
        IScore _IScore = _remote.GetScore();
        List<WCFThree.Entity.score> scoreList = _IScore.GetList_Stu(stu2.sno);
        foreach (var item in scoreList)
        {
            Console.WriteLine(string.Format("{0}-{1}", item.sno, item.degree));
        }
    
        //获取关联表数据方式2
        WCFThree.Entity.student stu3 = _IStudent.GetModel_Related("101");
        Console.WriteLine(stu3.sname);
        Console.WriteLine(stu3.scores.Count);
        Console.WriteLine(stu3.scores.First().degree);

    二.其他参考实例:

    http://www.cnblogs.com/guozili/archive/2012/09/03/2667429.html

  • 相关阅读:
    EF里如何定制实体的验证规则和实现IObjectWithState接口进行验证以及多个实体的同时验证
    EF里查看/修改实体的当前值、原始值和数据库值以及重写SaveChanges方法记录实体状态
    使用EF自带的EntityState枚举和自定义枚举实现单个和多个实体的增删改查
    EF里单个实体的增查改删以及主从表关联数据的各种增删改查
    EF和MVC系列文章导航:EF Code First、DbContext、MVC
    EF如何操作内存中的数据以及加载相关联表的数据:延迟加载、贪婪加载、显示加载
    EF里的继承映射关系TPH、TPT和TPC的讲解以及一些具体的例子
    Git敏捷开发--rebase命令
    浏览器远程编写python代码--jupyter web server
    C++学习--编译优化
  • 原文地址:https://www.cnblogs.com/tianma3798/p/5538279.html
Copyright © 2020-2023  润新知