• 终于尝试了一次EF


        其实我对微软出的Linq to Sql,以及Linq to Entity这两个产品兴趣都不大,不太喜欢那种开发模式,主要原因如下:
        1:自动生成的那堆代码,不利于平时的分层模式,将实体以及存储逻辑混合在一起总觉的不是那么回事;
        2:对于编写测试用例不是那么友好,全部逻辑都在一起,无法拆分测试,比如只想测试代码逻辑,不需要连接真正的数据库等。
        3:在排除程序BUG时,还是习惯于看直观的SQL,这样在数据库中调试起来更加容易些,可能是个人习惯问题;
        4:据说性能上存在一定缺陷,本人并未测试过,道听途说而已。

        之所以这次想尝试一次,主要基于两点:首先我现在接手的一个项目是用EF编写的,其次就是EF 4.2能够将原来混合在一起的代码给分离开,说的官方点,这个分离功能叫POCO,英文全名是Plain Old CLR Object,翻译成中文是简单传统的CLR对象。总之最新的EF允许开发人员手工编写更多代码,不再一味的依赖代码自动生成。

        第一:如何安装EF 4.2?

        我电脑上原来安装的是EF 4.0,这次选择的是通过NuGet方式安装。
        1:首先从VS菜单上选择工具,然后选择扩展管理,如下图。
          
       

          2:在弹出框的左侧选择Online,然后在右上角搜索Nuget,最后进行安装。

    ,
          

        3:安装NUGET后,我们在工程的引用中点击右键,就会多出一项来,如下所示。

            

        4:添加EF引用。点击上图中的最后一项,搜索EntityFramework,就会看到最新的EF了,选择进行添加即可。

            

        第二:创建EF程序。
     
        我采用的是最早的模式,即先有数据库,然后再有程序的模式,程序分了如下几层:

           

        1:ModelFirstSample.DAL,这是数据层,用于存放与数据库打交道的逻辑;
          先按正常流程添加一个ADO.NET Entity Data Model,按步就班,一步一步下来就行。这样会生成一个.edmx的文件。

          

         然后打开edmx文件,点击右键选择添加代码生成项,在弹出的菜单中选择Db context那项,接下来会生成PersonModel.tt,PersonModel.Context.tt两文件,对应的edmx下面的自动生成的代码已经为空了。    

     

          

        2:ModelFirstSample.Model,实体层,将EF生成的.edmx,.tt文件放在这,与存储逻辑分离;
          将第一步生成的PersonModel.edmx,PersonModel.tt添加到工程下面,同时删除原文件,这样就实现了实体层与存储逻辑的分离。
        3:ModelFirstSample.BLL,业务逻辑层,不用多说;
        4:ModelFirstSample.Service,服务层,对于业务逻辑层的进一步包装;
        5:ModelFirstSample.ConsoleApp,UI层。

        第三:EF中的开发模式之Repository。

        在实际项目中,如果希望能够对存储逻辑有一定的控制,于是就有了repository模式的出现,也就是对原始存储逻辑的一种封装。
        1:在接口层中创建一个通用的存储接口IRepository<T>,便于逻辑复用。

    public interface IRepository<T> where T : classnew()
        {
            T Create();
            T Update(T entity);
            T Insert(T entity);
            void Delete(T entity);
            T Find(params object[] keyValues);
            List<T> FindAll();
        }


        2:在DAL层中创建一个实现了IRepository<T>接口的RepositoryBase<T>基类,主要的就是需要提供一个DbContext,基本思想就是利用DbContext的Set<T>构造的类型来提供封装,这里就不做多的说明了,我这里为了简单,使用了默认构造方法,FacePerfEntities是添加edmx时生成的类。
       

    View Code
    public class RepositoryBase<T> : IRepository<T> where T : class,new()
        {
            public DbContext context;

            public RepositoryBase(DbContext _context)
            {
                this.context = _context;
            }
            public RepositoryBase()
            {
                this.context = new FacePerfEntities();
            }
            #region IRepository<T> 成员

            public T Create()
            {
                return context.Set<T>().Create();
            }

            public T Update(T entity)
            {
                if (context.Entry<T>(entity).State == EntityState.Modified)
                    context.SaveChanges();
                return entity;
            }

            public T Insert(T entity)
            {
                context.Set<T>().Add(entity);
                context.SaveChanges();
                return entity;
            }

            public void Delete(T entity)
            {
                context.Set<T>().Remove(entity);
                context.SaveChanges();
            }

            public T Find(params object[] keyValues)
            {
                return context.Set<T>().Find(keyValues);
            }

            public List<T> FindAll()
            {
                return context.Set<T>().ToList();
            }

            #endregion
        }

        3:在接口层中创建一个关于员工的接口:IEmployeeRepository<T>
       

    public  interface IEmployeeRepository<T>
        {
           List<T> SearchEmployee();

        }

        4:在业务逻辑层中创建关于员工的专用类:EmployeeRepositoryBLL。
       

    public class EmployeeRepositoryBLL : IEmployeeRepository<Employee>
        {
            EmployeeRepository repository = new EmployeeRepository();
            public List<Employee> SearchEmployee()
            {
                return repository.FindAll();
            }

        }

        5:在服务层中创建员工的服务类,由于这只是测试用,所以服务类起的作用并不明显,至于为什么有服务层,是为了将UI层与业务逻辑层分离等等众多原因。

    View Code
    public  class EmployeeRepositoryService
        {
           EmployeeRepositoryBLL repositoryEmployee=null  ;
           public EmployeeRepositoryService()
           {
              repositoryEmployee = new EmployeeRepositoryBLL();
           }
           public List<Employee> SearchEmployee()
           {
              return this.repositoryEmployee.SearchEmployee();
              
           }
        }

       

        6:最后就是UI了。
       

    View Code
    static void Main(string[] args)
            {
                EmployeeRepositoryService ers = new EmployeeRepositoryService();
                var list = ers.SearchEmployee();
                var people = from p in list
                             orderby p.CreatedOn
                             select p;

                Console.WriteLine("All People:");
                foreach (var person in people)
                {
                    Console.WriteLine("- {0}", person.ChineseName);
                }
                Console.WriteLine("Press any key to exit...");
                Console.ReadKey();
            }


         补充说明:

         1:添加完edmx后,以及完成添加代码生成项后,查询PersonModel.Context.cs,代码如下:
        

    public FacePerfEntities()
                : base("name=FacePerfEntities")
            {
            }

           构造函数中的参数FacePerfEntities,其实就对应EF数据库连接串的节点名称。

         2:添加完edmx后,在DAL层还会有一个packages.config文件,这个文件不用发布到UI程序下面,也不影响程序运行,只需要将连接串对应的节点复制到UI配置文件中即可。

         总结: 经过上面的改造,已经越来越适合实际项目了,EF在不断改进,我想在一些小型项目中快速开发倒是蛮适合的。

    注:本文参考

               http://blogs.msdn.com/b/adonet/archive/2011/09/28/ef-4-2-model-amp-database-first-walkthrough.aspx

               http://www.cnblogs.com/mecity/archive/2011/07/07/2099598.html

               http://www.cnblogs.com/chsword/archive/2011/09/14/NuGet_Install_OperatePackage.html

          

  • 相关阅读:
    Ehcache缓存配置
    spring3使用task:annotation-driven开始定时
    Constructor >> @Autowired >> @PostConstruct
    面试转载
    阿里面试:MYSQL的引擎区别
    Redis的主从复制的原理介绍
    微服务的调用链
    java的零拷贝机制
    存储过程与触发器面试
    ABA问题
  • 原文地址:https://www.cnblogs.com/ASPNET2008/p/2286244.html
Copyright © 2020-2023  润新知