菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型

系列概述:全系列会详细介绍抽象工厂三层的搭建,以及EF高级应用和 ASP.NET MVC3.0简单应用,应用到的技术有Ef、Lambda、Linq、Interface、T4等。 由于网上对涉及到的技术概念介绍很多,因此本项目中不再对基本概念加以叙述。

 
  

系列一概述:详细介绍如何使用Ef快速创建领域模型并生成数据库,适合EF零基础朋友学习。

 
一、创建项目解决方案
   1.1 创建空解决方案
       菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第1张图片
   1.2 创建Domain程序集
       菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第2张图片
二、创建ADO.NET实体数据模型
   2.1 在刚创建Domain程序集中创建EF
       菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第3张图片  
   2.2 选择空模型
       菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第4张图片  
   2.3 Ef添加完成
       菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第5张图片
 三、创建实体对象
    3.1 在edmx编辑器空白处点击鼠标右键创建实体对象
        菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第6张图片
    3.2 创建属性
        7
    3.3 实体对象创建完成
        菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第7张图片
    3.4 添加对应关系(一个用户可以对应多条日志信息)
        7.2
        菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第8张图片
     3.5 实体对象关系添加完成
       菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第9张图片
四、生成数据表
    4.1 edmx 设计器空白处右键选择根据模型生成数据库
       菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第10张图片
    4.2 执行生成的sql语句
       11
    4.3 执行完成
       菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第11张图片
五、查看数据库
EF很聪明会帮我们自动创建主外键和索引
    菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第12张图片




系列二概述:该系列详细介绍了如何抽象出公用方法(CRUD),以及T4模版的应用。
 
    一、创建Cnblogs.Rdst.IDAO程序集 
   
1.1 先在解决方案中创建一个Interface 文件夹,用于存放抽象出的接口
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第13张图片
 
1.2 在Interface文件夹中添加名为Cnblogs.Rdst.IDAO的程序集
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第14张图片
 
1.3 添加引用系列一中创建的Domain程序集和System.Data.Entity程序集
 
 
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第15张图片           
 
二、抽象数据访问层的基接口
 
2.1 在刚创建的Cnblogs.Rdst.IDAO程序集中创建IBaseDao接口
 
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第16张图片
2.2 在IBaseDao中定义常用的CRUD方法
复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace Cnblogs.Rdst.IDAO
 7 {
 8    public interface IBaseDao
 9                  where T:class,
10                  new ()//约束T类型必须可以实例化
11    {
12        //根据条件获取实体对象集合
13        IQueryable LoadEntites(Funcbool> whereLambda );
14 
15        //根据条件获取实体对象集合分页
16        IQueryable LoadEntites(Funcbool> whereLambda, int pageIndex, int pageSize,out int totalCount);
17 
18        //增加
19        T AddEntity(T entity);
20 
21        //更新
22        T UpdateEntity(T entity);
23 
24        //删除
25        bool DelEntity(T entity);
26 
27        //根据条件删除
28        bool DelEntityByWhere(Funcbool> whereLambda);
29    }
30 }
复制代码

 

              此时基接口中的CRUD方法就定义完成。接下来我们需要使用T4模版生成所有的实体类接口并实现IBaseDao接口。

    三、生成所有的实体类接口

          3.1 添加名为IDaoExt 的T4文本模版

             菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第17张图片

 

          3.2 在模版中贴入以下代码,其中注释的地方需要根据各自的项目进行更改

 

<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#><#@
 output extension=".cs"#>
<#
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);

string inputFile = @"..\\Cnblogs.Rdst.Domain\\Model.edmx";//指定edmx实体模型所在的路径

EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);

#>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.Domain;//引用Domain的命名空间

namespace Cnblogs.Rdst.IDAO //实体类接口所在的命名空间
{
<#
foreach (EntityType entity in ItemCollection.GetItems().OrderBy(e => e.Name)) //便利edmx模型中映射的实体对象
{#>    
    public interface I<#=entity.Name#>Dao:IBaseDao<<#=entity.Name#>> //生成实体对象接口
    {
    }
<#};#>
}

 

        3.3 T4模版编辑完成后,Ctrl+s保存,提示是否运行,点击确认。此时就自动帮我们生成了所有的实体类接口,并实现了IBaseDao接口,相应的也具有了CRUD方法定义。

        菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第18张图片         

       菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第19张图片

 

系列二概述:该系列详细介绍了如何抽象出公用方法(CRUD),以及T4模版的应用。
 
    一、创建Cnblogs.Rdst.IDAO程序集 
   
1.1 先在解决方案中创建一个Interface 文件夹,用于存放抽象出的接口
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第20张图片
 
1.2 在Interface文件夹中添加名为Cnblogs.Rdst.IDAO的程序集
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第21张图片
 
1.3 添加引用系列一中创建的Domain程序集和System.Data.Entity程序集
 
 
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第22张图片           
 
二、抽象数据访问层的基接口
 
2.1 在刚创建的Cnblogs.Rdst.IDAO程序集中创建IBaseDao接口
 
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第23张图片
2.2 在IBaseDao中定义常用的CRUD方法
复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace Cnblogs.Rdst.IDAO
 7 {
 8    public interface IBaseDao
 9                  where T:class,
10                  new ()//约束T类型必须可以实例化
11    {
12        //根据条件获取实体对象集合
13        IQueryable LoadEntites(Funcbool> whereLambda );
14 
15        //根据条件获取实体对象集合分页
16        IQueryable LoadEntites(Funcbool> whereLambda, int pageIndex, int pageSize,out int totalCount);
17 
18        //增加
19        T AddEntity(T entity);
20 
21        //更新
22        T UpdateEntity(T entity);
23 
24        //删除
25        bool DelEntity(T entity);
26 
27        //根据条件删除
28        bool DelEntityByWhere(Funcbool> whereLambda);
29    }
30 }
复制代码

 

              此时基接口中的CRUD方法就定义完成。接下来我们需要使用T4模版生成所有的实体类接口并实现IBaseDao接口。

    三、生成所有的实体类接口

          3.1 添加名为IDaoExt 的T4文本模版

             菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第24张图片

 

          3.2 在模版中贴入以下代码,其中注释的地方需要根据各自的项目进行更改

 

<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#><#@
 output extension=".cs"#>
<#
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);

string inputFile = @"..\\Cnblogs.Rdst.Domain\\Model.edmx";//指定edmx实体模型所在的路径

EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);

#>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.Domain;//引用Domain的命名空间

namespace Cnblogs.Rdst.IDAO //实体类接口所在的命名空间
{
<#
foreach (EntityType entity in ItemCollection.GetItems().OrderBy(e => e.Name)) //便利edmx模型中映射的实体对象
{#>    
    public interface I<#=entity.Name#>Dao:IBaseDao<<#=entity.Name#>> //生成实体对象接口
    {
    }
<#};#>
}

 

        3.3 T4模版编辑完成后,Ctrl+s保存,提示是否运行,点击确认。此时就自动帮我们生成了所有的实体类接口,并实现了IBaseDao接口,相应的也具有了CRUD方法定义。

        菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第25张图片         

       菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第26张图片

 


概要:1、实现EF上线文线程唯一,有效避免了脏数据问题。

         2、实现IBaseDao中定义的CRUD方法

一、创建数据访问层程序集

      1.1 在解决方案中创建Implements文件夹,以存放实现体部分的程序集          

          菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第27张图片

      1.2 在Implements文件夹中创建Cnblogs.Rdst.Dao程序集

         菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第28张图片

      1.3 添加如下引用

          菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第29张图片

二、创建ObjectContextFactory获取EF上下文

      2.1 在Cnblogs.Rdst.Dao程序集中创建ObjectContextFactory类,用来获取EF上下文。

            当数据库更换为Mysql或其他数据库时,在这个类中可以实现替换。

            当网站访问量增大时,为避免EF产生的脏数据问题,我们使用System.Runtime.Remoting.Messaging 命名空间下的CallContext来解决线程内上下文唯一。

            CallContex更多了解http://msdn.microsoft.com/zh-cn/library/system.runtime.remoting.messaging.callcontext(v=VS.80).aspx

     2.2  在ObjectContextFactory类中定义一个静态方法,用于对EF上下文进行处理

复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Data.Objects;
 4 using System.Linq;
 5 using System.Runtime.Remoting.Messaging;
 6 using System.Text;
 7 using Cnblogs.Rdst.Domain;
 8 using Cnblogs.Rdst.IDAO;
 9 
10 namespace Cnblogs.Rdst.Dao
11 {
12    public class ObjectContextFactory
13     {
14         public static System.Data.Objects.ObjectContext GetCurrentObjectContext()
15         {
16             //从CallContext数据槽中获取EF上下文
17             ObjectContext objectContext = CallContext.GetData(typeof (ObjectContextFactory).FullName) as ObjectContext;
18             if (objectContext==null)
19             {
20                 //如果CallContext数据槽中没有EF上下文,则创建EF上下文,并保存到CallContext数据槽中
21                 objectContext = new ModelContainer();//当数据库替换为MySql等,只要在次出EF更换上下文即可。
22                 CallContext.SetData(typeof(ObjectContextFactory).FullName,objectContext);
23             }
24             return objectContext;
25         }
26     }
27 }
复制代码

 

三、创建BaseDao,并实现CRUD方法

      3.1 创建BaseDao类,实现IBaseDao中定义方法,用于所有实体类继承此基类。

           菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第30张图片

     3.2 BaseDao类实现代码

           EF应用中需要注意:1、增加和查询是不需要附加实体的,如果删除和更新不是从上下文获取的实体,就需要先附加,再进行状态更改。

                                     2、处理查询,增删改都需要调用SaveChange()提交操作。

复制代码
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Data.Objects;
  4 using System.Linq;
  5 using System.Text;
  6 using Cnblogs.Rdst.IDAO;
  7 
  8 
  9 namespace Cnblogs.Rdst.Dao
 10 {
 11    public  class BaseDao
 12                  where T:class,
 13                  new()
 14                     
 15    {
 16        ObjectContext objectContext= ObjectContextFactory.GetCurrentObjectContext() as ObjectContext;//获取EF上下文
 17 
 18        /// 
 19        /// 加载实体集合
 20        /// 
 21        /// 
 22        /// 
 23        public virtual IQueryable LoadEntites(Funcbool> whereLambda)
 24        {
 25           return objectContext.CreateObjectSet().Where(whereLambda).AsQueryable();
 26        }
 27 
 28        /// 
 29        /// 分页加载数据
 30        /// 
 31        /// 过滤条件
 32        /// 页码
 33        /// 页大小
 34        /// 总记录数
 35        /// 
 36        public virtual IQueryable LoadEntites(Funcbool> whereLambda, int pageIndex, int pageSize, out int totalCount)
 37        {
 38           var tmp= objectContext.CreateObjectSet().Where(whereLambda);
 39           totalCount = tmp.Count();
 40 
 41           return tmp.Skip(pageSize * (pageIndex - 1))//跳过行数,最终生成的sql语句是Top(n)
 42                     .Take(pageSize) //返回指定数量的行
 43                     .AsQueryable();
 44        }
 45 
 46        /// 
 47        /// 添加实体
 48        /// 
 49        /// 
 50        /// 返回更新后的实体
 51        public virtual T AddEntity(T entity)
 52        {
 53            objectContext.CreateObjectSet().AddObject(entity);
 54            objectContext.SaveChanges();
 55            return entity;
 56        }
 57 
 58        /// 
 59        /// 更新实体
 60        /// 
 61        /// 
 62        /// 返回更新后的实体
 63        public virtual T UpdateEntity(T entity)
 64        {
 65            objectContext.CreateObjectSet().Attach(entity);
 66            objectContext.ObjectStateManager.ChangeObjectState(entity, System.Data.EntityState.Modified);//将附加的对象状态更改为修改
 67            objectContext.SaveChanges();
 68            return entity;
 69        }
 70 
 71        /// 
 72        /// 删除实体
 73        /// 
 74        /// 
 75        /// 
 76        public virtual bool DelEntity(T entity)
 77        {
 78            objectContext.CreateObjectSet().Attach(entity);
 79            objectContext.ObjectStateManager.ChangeObjectState(entity, System.Data.EntityState.Deleted);//将附加的实体状态更改为删除
 80            if (objectContext.SaveChanges()>0)
 81            {
 82                return true;//删除成功
 83            }
 84            else
 85            {
 86                return false;//删除失败
 87            }
 88        }
 89 
 90        /// 
 91        /// 根据条件删除对象
 92        /// 
 93        /// 条件
 94        /// 
 95        public virtual bool DelEntityByWhere(Funcbool> whereLambda)
 96        {
 97           var tmp= objectContext.CreateObjectSet().Where(whereLambda);//根据条件从数据库中获取对象集合
 98           foreach (var entity in tmp)
 99           {
100               objectContext.CreateObjectSet().DeleteObject(entity);//标记对象为删除状态删除
101           }
102           if (objectContext.SaveChanges() > 0) 
103           {
104               return true;
105           }
106           else
107           {
108               return false;
109           }
110        }
111    }
112 }
复制代码

 

四、使用T4模版生成所有实体对象的实现

      4.1 和系列二中的方法一样创建T4模版,生成所有的实体类继承自BaseDao并实现各自的接口

           以下是T4模版中的代码,需要更改相应的EF edmx模型路径、引用命名空间等。

复制代码
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#><#@
 output extension=".cs"#>
<#
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);

string inputFile = @"..\\Cnblogs.Rdst.Domain\\Model.edmx";

EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
#>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.IDAO;
using Cnblogs.Rdst.Domain;

namespace Cnblogs.Rdst.Dao
{
<#
foreach (EntityType entity in ItemCollection.GetItems().OrderBy(e => e.Name))
{#>    
    public partial class <#=entity.Name#>Dao:BaseDao<<#=entity.Name#>>,I<#=entity.Name#>Dao
    {
      
    }
<#};#>
}
复制代码

      4.2 T4模版编辑完成后,ctrl+s保存并运行,就生成了所有实体类的实现了

 

菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第31张图片

至此也就实现了数据访问层的增删改查以及分页查询。

菜鸟级三层框架(EF+MVC)项目实战之 系列二 对数据访问层的抽象下 将实现数据访问层对业务层的统一入口

系列二概述:该系列详细介绍了如何抽象出公用方法(CRUD),以及T4模版的应用。
 
    一、创建Cnblogs.Rdst.IDAO程序集 
   
1.1 先在解决方案中创建一个Interface 文件夹,用于存放抽象出的接口
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第32张图片
 
1.2 在Interface文件夹中添加名为Cnblogs.Rdst.IDAO的程序集
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第33张图片
 
1.3 添加引用系列一中创建的Domain程序集和System.Data.Entity程序集
 
 
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第34张图片           
 
二、抽象数据访问层的基接口
 
2.1 在刚创建的Cnblogs.Rdst.IDAO程序集中创建IBaseDao接口
 
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第35张图片
2.2 在IBaseDao中定义常用的CRUD方法
复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace Cnblogs.Rdst.IDAO
 7 {
 8    public interface IBaseDao
 9                  where T:class,
10                  new ()//约束T类型必须可以实例化
11    {
12        //根据条件获取实体对象集合
13        IQueryable LoadEntites(Funcbool> whereLambda );
14 
15        //根据条件获取实体对象集合分页
16        IQueryable LoadEntites(Funcbool> whereLambda, int pageIndex, int pageSize,out int totalCount);
17 
18        //增加
19        T AddEntity(T entity);
20 
21        //更新
22        T UpdateEntity(T entity);
23 
24        //删除
25        bool DelEntity(T entity);
26 
27        //根据条件删除
28        bool DelEntityByWhere(Funcbool> whereLambda);
29    }
30 }
复制代码

 

              此时基接口中的CRUD方法就定义完成。接下来我们需要使用T4模版生成所有的实体类接口并实现IBaseDao接口。

    三、生成所有的实体类接口

          3.1 添加名为IDaoExt 的T4文本模版

             菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第36张图片

 

          3.2 在模版中贴入以下代码,其中注释的地方需要根据各自的项目进行更改

 

<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#><#@
 output extension=".cs"#>
<#
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);

string inputFile = @"..\\Cnblogs.Rdst.Domain\\Model.edmx";//指定edmx实体模型所在的路径

EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);

#>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.Domain;//引用Domain的命名空间

namespace Cnblogs.Rdst.IDAO //实体类接口所在的命名空间
{
<#
foreach (EntityType entity in ItemCollection.GetItems().OrderBy(e => e.Name)) //便利edmx模型中映射的实体对象
{#>    
    public interface I<#=entity.Name#>Dao:IBaseDao<<#=entity.Name#>> //生成实体对象接口
    {
    }
<#};#>
}

 

        3.3 T4模版编辑完成后,Ctrl+s保存,提示是否运行,点击确认。此时就自动帮我们生成了所有的实体类接口,并实现了IBaseDao接口,相应的也具有了CRUD方法定义。

        菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第37张图片         

       菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第38张图片

 


概述:1、对数据访问层进行封装

         2、对业务层提供统一入口

         3、线程内实例唯一

一、数据访问层封装抽象

    1.1、在程序集Cnblogs.Rdst.IDAO中创建IDBSession接口,其主要目的是将所有实体类封装为属性。

           菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第39张图片

    1.2、IDBSession接口中定义SaveChange()方法,定义该方法的意义会在业务逻辑中介绍。

复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace Cnblogs.Rdst.IDAO
 7 {
 8     public partial interface IDBSession
 9     {
10         int SaveChange();//用于在业务逻辑层对提交进行管理
11     }
12 }
复制代码

     1.3、创建名为IDBSessionExt的T4模版,实现自动生成IDBSession的部分接口,其中将所有实体类定义为接口属性,以实现对数据访问层的封装。
 

复制代码
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#><#@
 output extension=".cs"#>
<#
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);

string inputFile = @"..\\Cnblogs.Rdst.Domain\\Model.edmx";

EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);

#>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.Domain;

namespace Cnblogs.Rdst.IDAO
{
  public partial interface IDBSession
  {
    <#foreach (EntityType entity in ItemCollection.GetItems().OrderBy(e => e.Name))
    {#>    
        I<#=entity.Name#>Dao <#=entity.Name#>Dao { get; set; }
    <#};#>
 }
}
复制代码

    1.4、T4模版编辑完成后,运行后生成的代码如下:

        菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第40张图片

 

二、数据访问层统一入口抽象

      在程序集Cnblogs.Rdst.IDAO中创建IDbSessionFactory接口,为业务逻辑层提供统一访问入口。

      该接口中定义GetCurrentDBSession()方法,其作用是通过该接口方法获取需要的实体对象。       

复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace Cnblogs.Rdst.IDAO
 7 {
 8     public interface IDBSessionFactory
 9     {
10         IDBSession GetCurrentDBSession();
11     }
12 }
复制代码

三、实现IDBSession

   3.1、在Cnblogs.Rdst.Dao程序集中创建DBSession 部分类

          菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第41张图片

   3.2、在Cnblogs.Rdst.Dao程序集中创建名为DBSessionExt的T4模版,将所有实体类自动封装为属性,以下是T4模版中的代码  

复制代码
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#><#@
 output extension=".cs"#>
<#
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);

string inputFile = @"..\\Cnblogs.Rdst.Domain\\Model.edmx";

EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);

#>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.IDAO;

namespace Cnblogs.Rdst.Dao
{
  public partial class DBSession : IDBSession
  {
    <#foreach (EntityType entity in ItemCollection.GetItems().OrderBy(e => e.Name))
    {#>    
        private I<#=entity.Name#>Dao _<#=entity.Name#>Dao;
        public I<#=entity.Name#>Dao <#=entity.Name#>Dao
        {
            get
            {
                if (_<#=entity.Name#>Dao == null)
                {
                    _<#=entity.Name#>Dao = new <#=entity.Name#>Dao();
                }
                return _<#=entity.Name#>Dao;
            }
            set { _<#=entity.Name#>Dao = value; }
        }
    <#}#>
 }
}
复制代码

    3.3保存模版并运行,T4模版会自动将所有实体对象封装为属性。如下代码所示:

复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using Cnblogs.Rdst.IDAO;
 6 
 7 namespace Cnblogs.Rdst.Dao
 8 {
 9   public partial class DBSession : IDBSession
10   {
11         
12         private INoteInfoDao _NoteInfoDao;
13         public INoteInfoDao NoteInfoDao
14         {
15             get
16             {
17                 if (_NoteInfoDao == null)
18                 {
19                     _NoteInfoDao = new NoteInfoDao();
20                 }
21                 return _NoteInfoDao;
22             }
23             set { _NoteInfoDao = value; }
24         }
25         
26         private IUserInfoDao _UserInfoDao;
27         public IUserInfoDao UserInfoDao
28         {
29             get
30             {
31                 if (_UserInfoDao == null)
32                 {
33                     _UserInfoDao = new UserInfoDao();
34                 }
35                 return _UserInfoDao;
36             }
37             set { _UserInfoDao = value; }
38         }
39      }
40 }
复制代码

     3.4、打开刚创建的DBSession类,实现IDBSession接口。并重新SaveChanges()方法,SaveChange()方法中调用了EF上下文中的SaveChange(),

            其用途会在业务逻辑层进行详细说明。

            以下是DBSession类中的实现代码:

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.IDAO;
using System.Data.Objects;

namespace Cnblogs.Rdst.Dao
{
    public partial class DBSession : IDBSession
    {
        private ObjectContext _efContext;

        //EF上下文
        public ObjectContext EfContext
        {
            get
            {
                if (_efContext == null)
                {
                  _efContext= ObjectContextFactory.GetCurrentObjectContext();
                }
                return _efContext;
            }
            set { _efContext = value; }
        }

        public int SaveChange()
        {
            return EfContext.SaveChanges();//调用SaveChanges()方法提交操作
        }


    }
}
复制代码

四、实现数据访问层统一入口
      接下来现在我们需要在Cnblogs.Rdst.Dao程序集中实现IDbSessionFactory接口

      创建DBSessionFactory类并实现IDbSessionFactory接口,为了避免资源浪费,也用到了CallContex实现了线程内实例唯一。

      以下是DBsessionFactory类中的实现代码:

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.IDAO;
using System.Runtime.Remoting.Messaging;

namespace Cnblogs.Rdst.Dao
{
   public class DBSessionFactory:IDBSessionFactory
    {
        public IDBSession GetCurrentDBSession()
        {
            IDBSession dbSession = CallContext.GetData(typeof(DBSessionFactory).FullName) as DBSession;
            if (dbSession == null)
            { 
               dbSession=new DBSession();
               CallContext.SetData(typeof(DBSessionFactory).FullName, dbSession);
            }
            return dbSession;
        }
    }
}
复制代码


至此,我们就已经完成了对数据访问层的封装。

总结:1、方便了对数据库的替换数据库,只需要在ObjectContextFactory中进行替换相应的FE上下文。

         2、当数据库中的表或字段有更新时,我们只需要重新运行一下相应T4模版,就可以实现与数据库保存一致。

接下来的系列三中会介绍业务逻辑层是如何调用数据访问层,稍后会进行更新。  



系列二概述:该系列详细介绍了如何抽象出公用方法(CRUD),以及T4模版的应用。
 
    一、创建Cnblogs.Rdst.IDAO程序集 
   
1.1 先在解决方案中创建一个Interface 文件夹,用于存放抽象出的接口
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第42张图片
 
1.2 在Interface文件夹中添加名为Cnblogs.Rdst.IDAO的程序集
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第43张图片
 
1.3 添加引用系列一中创建的Domain程序集和System.Data.Entity程序集
 
 
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第44张图片           
 
二、抽象数据访问层的基接口
 
2.1 在刚创建的Cnblogs.Rdst.IDAO程序集中创建IBaseDao接口
 
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第45张图片
2.2 在IBaseDao中定义常用的CRUD方法
复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace Cnblogs.Rdst.IDAO
 7 {
 8    public interface IBaseDao
 9                  where T:class,
10                  new ()//约束T类型必须可以实例化
11    {
12        //根据条件获取实体对象集合
13        IQueryable LoadEntites(Funcbool> whereLambda );
14 
15        //根据条件获取实体对象集合分页
16        IQueryable LoadEntites(Funcbool> whereLambda, int pageIndex, int pageSize,out int totalCount);
17 
18        //增加
19        T AddEntity(T entity);
20 
21        //更新
22        T UpdateEntity(T entity);
23 
24        //删除
25        bool DelEntity(T entity);
26 
27        //根据条件删除
28        bool DelEntityByWhere(Funcbool> whereLambda);
29    }
30 }
复制代码

 

              此时基接口中的CRUD方法就定义完成。接下来我们需要使用T4模版生成所有的实体类接口并实现IBaseDao接口。

    三、生成所有的实体类接口

          3.1 添加名为IDaoExt 的T4文本模版

             菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第46张图片

 

          3.2 在模版中贴入以下代码,其中注释的地方需要根据各自的项目进行更改

 

<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#><#@
 output extension=".cs"#>
<#
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);

string inputFile = @"..\\Cnblogs.Rdst.Domain\\Model.edmx";//指定edmx实体模型所在的路径

EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);

#>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.Domain;//引用Domain的命名空间

namespace Cnblogs.Rdst.IDAO //实体类接口所在的命名空间
{
<#
foreach (EntityType entity in ItemCollection.GetItems().OrderBy(e => e.Name)) //便利edmx模型中映射的实体对象
{#>    
    public interface I<#=entity.Name#>Dao:IBaseDao<<#=entity.Name#>> //生成实体对象接口
    {
    }
<#};#>
}

 

        3.3 T4模版编辑完成后,Ctrl+s保存,提示是否运行,点击确认。此时就自动帮我们生成了所有的实体类接口,并实现了IBaseDao接口,相应的也具有了CRUD方法定义。

        菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第47张图片         

       菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第48张图片

 


概述:业务逻辑层封装相对数据访问层来说较为简单,我们分为以下几步:

         1、抽象基接口定义CRUD方法

         2、应用T4模版生成所有实体接口

         3、接口实现

一、接口定义

     1.1、创建名为Cnblogs.Rdst.IBLL的程序集,主要用于业务逻辑层接口定义

             并引用Cnblogs.Rdst.Domain和System.Data.Entity。这里需要注意,只要是用到EF实体,就需要添加System.Data.Entity引用。

            

            菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第49张图片

       1.2、创建IBaseService接口定义CRUD方法

              这里可以直接将IBaseDao中定义的方法拷贝过来。

            

复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace Cnblogs.Rdst.IBLL
 7 {
 8     public interface IBaseService
 9                        where T:class,
10                        new ()
11     {
12         //根据条件获取实体对象集合
13         IQueryable LoadEntites(Funcbool> whereLambda);
14 
15         //根据条件获取实体对象集合分页
16         IQueryable LoadEntites(Funcbool> whereLambda, int pageIndex, int pageSize, out int totalCount);
17 
18         //增加
19         T AddEntity(T entity);
20 
21         //更新
22         T UpdateEntity(T entity);
23 
24         //删除
25         bool DelEntity(T entity);
26 
27         //根据条件删除
28         bool DelEntityByWhere(Funcbool> whereLambda);
29     }
30 }
复制代码

      1.3、创建名为IServiceExt的T4模版,用于自动生成所有实体对象的接口,并继承自IBaseService接口
             以下是T4模版中的代码:

复制代码
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#><#@
 output extension=".cs"#>
<#
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);

string inputFile = @"..\\Cnblogs.Rdst.Domain\\Model.edmx";

EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
#>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.Domain;

namespace Cnblogs.Rdst.IBLL
{
<#
foreach (EntityType entity in ItemCollection.GetItems().OrderBy(e => e.Name))
{#>    
    public interface I<#=entity.Name#>Service : IBaseService<<#=entity.Name#>>
    {
    }
<#};#>
}
复制代码

        

        以下是T4模版运行后,自动为我们生成的代码:


       菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第50张图片

        至此,业务逻辑层的接口就定义完成了。

二、抽象出业务逻辑层的基类

      2.1、创建名为Cnblogs.Rdst.BLL程序集,并添加DAO、Domain、IBLL、IDAO、System.Data.Entity程序集引用,如下图

            菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第51张图片

    2.2、接下来是我们的重点,创建名为BaseService基类。该基类中实现了对数据访问层的调用,也实现了CRUD

           步骤: 1、先将IDBSessionFactory封装为属性,用于获取IDBSession

                     2、再将IDBSession封装为属性,用于获取EF上下文对象

                     3、定义IBaseDao类型的CurrentDao属性,用于属性获取具体的实体对象

                     4、定义抽象方法 SetCurrentDao(),用于子类设置实现,为CurrentDao属性赋具体的实体对象

          以下是这部分代码实现:

复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using Cnblogs.Rdst.IDAO;
 6 using Cnblogs.Rdst.Dao;
 7 
 8 
 9 namespace Cnblogs.Rdst.BLL
10 {
11     public abstract  class BaseService
12                     where T : class,
13                     new()
14     {
15         //构造函数
16         public BaseService()
17         {
18             //调用SetCurrentDao()方法,要求子类必须实现
19             SetCurrentDao();
20         }
21 
22         //获取EF实体工厂
23         IDBSessionFactory _dbSessionFactory;
24         IDBSession _dbSession;
25 
26         public IDBSessionFactory DbSessionFactory
27         {
28             get
29             {
30                 if (_dbSessionFactory == null)
31                 {
32                     _dbSessionFactory = new DBSessionFactory();
33                 }
34                 return _dbSessionFactory;
35             }
36             set { _dbSessionFactory = value; }
37         }
38 
39 
40         public IDBSession DbSession
41         {
42             get
43             {
44                 if (_dbSession == null)
45                 {
46                     _dbSession = DbSessionFactory.GetCurrentDBSession();//通过数据访问层提供的工厂获取EF实体对象
47                 }
48                 return _dbSession;
49             }
50             set { _dbSession = value; }
51         }
52         //数据访问层基接口类型可以接收数据访问层的所有实体Dao
53         public IBaseDao CurrentDao { get; set; }
54 
55         //该方法用于子类实现,其作用是设置相应的实体Dao
56         public abstract void SetCurrentDao();
          //以下是CRUD实现
复制代码

     2.3、实现CRUD
            有了EF上下文,我们就可以实现CRUD

            在实现增加和更新方法是,我们这时调用DBSessin中封装的SaveChanges()方法进行提交,主要目的是实现业务层控制提交。

            由于EF具有延迟加载特性,因此我们利用此特性,实现批量操作时,一次提交数据库,已提程序高性能。

            因此我们这时需要将BaseDao中的增加和更新方法中的SaveChange()方法注视掉,在此我就不贴出此部分代码了。

            以下是CRUD实现代码:

复制代码
 1         //以下是CRUD实现
 2 
 3         public virtual IQueryable LoadEntites(Funcbool> whereLambda)
 4         {
 5             return this.CurrentDao.LoadEntites(whereLambda);
 6         }
 7 
 8 
 9         public virtual IQueryable LoadEntites(Funcbool> whereLambda, int pageIndex, int pageSize, out int totalCount)
10         {
11             return this.CurrentDao.LoadEntites(whereLambda, pageIndex, pageSize, out totalCount);
12         }
13 
14 
15         public virtual T AddEntity(T entity)
16         {
17             var tmp= this.CurrentDao.AddEntity(entity);
18             this.DbSession.SaveChange();
19             return tmp;
20         }
21 
22 
23         public virtual T UpdateEntity(T entity)
24         {
25             var tmp= this.CurrentDao.UpdateEntity(entity);
26             this.DbSession.SaveChange();
27             return tmp;
28         }
29 
30 
31         public virtual bool DelEntity(T entity)
32         {
33             return this.CurrentDao.DelEntity(entity);
34         }
35 
36 
37         public virtual bool DelEntityByWhere(Funcbool> whereLambda)
38         {
39             return this.DelEntityByWhere(whereLambda);
40         }
41     }
42 }
复制代码

      至此,BaseService业务逻辑层基类就封装完成,接下来使用T4模版自动生成所有实体。

      2.4、创建名为ServiceExt的T4模版

             以下是模版中的代码:

复制代码
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#><#@
 output extension=".cs"#>
<#
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);

string inputFile = @"..\\Cnblogs.Rdst.Domain\\Model.edmx";

EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
#>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.IBLL;
using Cnblogs.Rdst.Domain;

namespace Cnblogs.Rdst.BLL
{
<#
foreach (EntityType entity in ItemCollection.GetItems().OrderBy(e => e.Name))
{#>    
    public partial class <#=entity.Name#>Service : BaseService<<#=entity.Name#>>, I<#=entity.Name#>Service
    {
       public override void SetCurrentDao()
       {
           this.CurrentDao = this.DbSession.<#=entity.Name#>Dao;
       }
    }
<#};#>
}
复制代码

        以下是运行T4模版后自动生成的代码:

菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第52张图片

 

这时我们就对业务逻辑层封装完成,系列四中使用MVC3.0简单实现增删改查以及分页功能。

系列二概述:该系列详细介绍了如何抽象出公用方法(CRUD),以及T4模版的应用。
 
    一、创建Cnblogs.Rdst.IDAO程序集 
   
1.1 先在解决方案中创建一个Interface 文件夹,用于存放抽象出的接口
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第53张图片
 
1.2 在Interface文件夹中添加名为Cnblogs.Rdst.IDAO的程序集
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第54张图片
 
1.3 添加引用系列一中创建的Domain程序集和System.Data.Entity程序集
 
 
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第55张图片           
 
二、抽象数据访问层的基接口
 
2.1 在刚创建的Cnblogs.Rdst.IDAO程序集中创建IBaseDao接口
 
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第56张图片
2.2 在IBaseDao中定义常用的CRUD方法
复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace Cnblogs.Rdst.IDAO
 7 {
 8    public interface IBaseDao
 9                  where T:class,
10                  new ()//约束T类型必须可以实例化
11    {
12        //根据条件获取实体对象集合
13        IQueryable LoadEntites(Funcbool> whereLambda );
14 
15        //根据条件获取实体对象集合分页
16        IQueryable LoadEntites(Funcbool> whereLambda, int pageIndex, int pageSize,out int totalCount);
17 
18        //增加
19        T AddEntity(T entity);
20 
21        //更新
22        T UpdateEntity(T entity);
23 
24        //删除
25        bool DelEntity(T entity);
26 
27        //根据条件删除
28        bool DelEntityByWhere(Funcbool> whereLambda);
29    }
30 }
复制代码

 

              此时基接口中的CRUD方法就定义完成。接下来我们需要使用T4模版生成所有的实体类接口并实现IBaseDao接口。

    三、生成所有的实体类接口

          3.1 添加名为IDaoExt 的T4文本模版

             菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第57张图片

 

          3.2 在模版中贴入以下代码,其中注释的地方需要根据各自的项目进行更改

 

<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#><#@
 output extension=".cs"#>
<#
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);

string inputFile = @"..\\Cnblogs.Rdst.Domain\\Model.edmx";//指定edmx实体模型所在的路径

EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);

#>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.Domain;//引用Domain的命名空间

namespace Cnblogs.Rdst.IDAO //实体类接口所在的命名空间
{
<#
foreach (EntityType entity in ItemCollection.GetItems().OrderBy(e => e.Name)) //便利edmx模型中映射的实体对象
{#>    
    public interface I<#=entity.Name#>Dao:IBaseDao<<#=entity.Name#>> //生成实体对象接口
    {
    }
<#};#>
}

 

        3.3 T4模版编辑完成后,Ctrl+s保存,提示是否运行,点击确认。此时就自动帮我们生成了所有的实体类接口,并实现了IBaseDao接口,相应的也具有了CRUD方法定义。

        菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第58张图片         

       菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第59张图片

 


概述:该节主要目的是通过ASP.Net MVC3.0快速实现增删改查

一、创建MVC项目

      1.1、在解决方案中添加MVC3.0项目

              vs2010中没有自带MVC3.0,下载:http://www.asp.net/mvc/mvc3

            菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第60张图片

             在这里我们选择“空”模版

           菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第61张图片

      1.2、添加相关引用

           1)由于使用的EF因此需要添加一坨相关引用,我们可以在MVC项目中的Model中添加一个ASP.NET 实体数据模型。此时VS会帮我们引用相应的程序集,完成后我再

                删除它。

           2) 再引用我们的程序集,Cnblogs.Rdst.IBLL、Cnblogs.Rdst.BLL、Cnblogs.Rdst.Domain

                

                菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第62张图片

            3、配置连接字符串

                将Cnblogs.Rdst.Domain中的App.Config文件里的

<connectionStrings>
    <add name="ModelContainer" connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=Cnblogs-Rdst;persist security info=True;user id=sa;password=Hell0F18;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
  connectionStrings>
拷贝到MVC项目中的web.config里的
<configuration>节点下,如下图:

菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第63张图片

 

 
  

二、添加UserInfo控制器

      2.1、在创建控制器前我们需要将解决方案编译一下。

      2.2、回到MVC项目中右键点击Controllers,创建一个名为UserInfo的控制器

           菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第64张图片

      2.3、“模型类”选择UserInfo实体类,“数据上下文”选择ModelContainer实体上下文,在此我们选择Razor实体引擎。

           菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第65张图片

三、快速实现CRUD

     3.1 此时VS会帮我们生成UserInfo和View下的一些页面

         菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第66张图片

    3.2 以下代码是UserInfoController控制器中增删改查的代码,其中注释掉的代码是vs自动生成的。

        

复制代码
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Data;
  4 using System.Data.Entity;
  5 using System.Linq;
  6 using System.Web;
  7 using System.Web.Mvc;
  8 using Cnblogs.Rdst.Domain;
  9 using Cnblogs.Rdst.IBLL;
 10 using Cnblogs.Rdst.BLL;
 11 
 12 namespace Cnblogs.Rdst.Mvc.Controllers
 13 { 
 14     public class UserInfoController : Controller
 15     {
 16         //private ModelContainer db = new ModelContainer();
 17         IUserInfoService db = new UserInfoService();
 18 
 19         //
 20         // GET: /UserInfo/
 21 
 22         public ViewResult Index()
 23         {
 24            // return View(db.UserInfo.ToList());
 25             return View(db.LoadEntites(u => true));
 26         }
 27 
 28         //
 29         // GET: /UserInfo/Details/5
 30 
 31         public ViewResult Details(int id)
 32         {
 33             //UserInfo userinfo = db.UserInfo.Single(u => u.ID == id);
 34             UserInfo userinfo = db.LoadEntites(u => u.ID == id).FirstOrDefault();//FirstOrDefault()获取集合第一项
 35             return View(userinfo);
 36         }
 37 
 38         //
 39         // GET: /UserInfo/Create
 40 
 41         public ActionResult Create()
 42         {
 43             return View();
 44         } 
 45 
 46         //
 47         // POST: /UserInfo/Create
 48 
 49         [HttpPost]
 50         public ActionResult Create(UserInfo userinfo)
 51         {
 52             if (ModelState.IsValid)
 53             {
 54                 //db.UserInfo.AddObject(userinfo);
 55                 //db.SaveChanges();
 56                 db.AddEntity(userinfo);
 57                 return RedirectToAction("Index");  
 58             }
 59 
 60             return View(userinfo);
 61         }
 62         
 63         //
 64         // GET: /UserInfo/Edit/5
 65  
 66         public ActionResult Edit(int id)
 67         {
 68             //UserInfo userinfo = db.UserInfo.Single(u => u.ID == id);
 69             UserInfo userinfo = db.LoadEntites(u=>u.ID==id).FirstOrDefault();
 70             return View(userinfo);
 71         }
 72 
 73         //
 74         // POST: /UserInfo/Edit/5
 75 
 76         [HttpPost]
 77         public ActionResult Edit(UserInfo userinfo)
 78         {
 79             if (ModelState.IsValid)
 80             {
 81                // db.UserInfo.Attach(userinfo);
 82                // db.ObjectStateManager.ChangeObjectState(userinfo, EntityState.Modified);
 83                // db.SaveChanges();
 84                 db.UpdateEntity(userinfo);
 85                 return RedirectToAction("Index");
 86             }
 87             return View(userinfo);
 88         }
 89 
 90         //
 91         // GET: /UserInfo/Delete/5
 92  
 93         public ActionResult Delete(int id)
 94         {
 95            // UserInfo userinfo = db.UserInfo.Single(u => u.ID == id);
 96             UserInfo userinfo = db.LoadEntites(u => u.ID == id).FirstOrDefault();
 97             return View(userinfo);
 98         }
 99 
100         //
101         // POST: /UserInfo/Delete/5
102 
103         [HttpPost, ActionName("Delete")]
104         public ActionResult DeleteConfirmed(int id)
105         {            
106             //UserInfo userinfo = db.UserInfo.Single(u => u.ID == id);
107            // db.UserInfo.DeleteObject(userinfo);
108            // db.SaveChanges();
109             var userInfo=db.LoadEntites(u=>u.ID==id).FirstOrDefault();
110             db.DelEntity(userInfo);
111             return RedirectToAction("Index");
112         }
113 
114         //protected override void Dispose(bool disposing)
115         //{
116         //    db.Dispose();
117         //    base.Dispose(disposing);
118         //}
119     }
120 }
复制代码

      3.3、接下来我们在Global.asax文件中配置一下路由,将controller = "Home"更改为controller = "UserInfo"

            

        菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第67张图片

        3.4、将Cnblogs.Rdst.Mvc项目设置为启动项,在点击启动调试。

               在此由于涉及到表外键关系,我们需要将映射文件中的外键改为可空,在网页上才可以进行新增操作。

       菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第68张图片

 

                  菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第69张图片

     至此,面向对象、面向接口 入门级三层架构项目就已结束了,希望对大家有所帮助!

     源码下载



系列二概述:该系列详细介绍了如何抽象出公用方法(CRUD),以及T4模版的应用。
 
     一、创建Cnblogs.Rdst.IDAO程序集 
    
1.1 先在解决方案中创建一个Interface 文件夹,用于存放抽象出的接口
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第70张图片
 
1.2 在Interface文件夹中添加名为Cnblogs.Rdst.IDAO的程序集
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第71张图片
 
1.3 添加引用系列一中创建的Domain程序集和System.Data.Entity程序集
 
 
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第72张图片           
 
二、抽象数据访问层的基接口
 
2.1 在刚创建的Cnblogs.Rdst.IDAO程序集中创建IBaseDao接口
 
菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第73张图片
2.2 在IBaseDao中定义常用的CRUD方法
复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace Cnblogs.Rdst.IDAO
 7 {
 8    public interface IBaseDao
 9                  where T:class,
10                  new ()//约束T类型必须可以实例化
11    {
12        //根据条件获取实体对象集合
13        IQueryable LoadEntites(Funcbool> whereLambda );
14 
15        //根据条件获取实体对象集合分页
16        IQueryable LoadEntites(Funcbool> whereLambda, int pageIndex, int pageSize,out int totalCount);
17 
18        //增加
19        T AddEntity(T entity);
20 
21        //更新
22        T UpdateEntity(T entity);
23 
24        //删除
25        bool DelEntity(T entity);
26 
27        //根据条件删除
28        bool DelEntityByWhere(Funcbool> whereLambda);
29    }
30 }
复制代码

 

              此时基接口中的CRUD方法就定义完成。接下来我们需要使用T4模版生成所有的实体类接口并实现IBaseDao接口。

    三、生成所有的实体类接口

          3.1 添加名为IDaoExt 的T4文本模版

             菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第74张图片

 

          3.2 在模版中贴入以下代码,其中注释的地方需要根据各自的项目进行更改

 

<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#><#@
 output extension=".cs"#>
<#
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);

string inputFile = @"..\\Cnblogs.Rdst.Domain\\Model.edmx";//指定edmx实体模型所在的路径

EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);

#>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cnblogs.Rdst.Domain;//引用Domain的命名空间

namespace Cnblogs.Rdst.IDAO //实体类接口所在的命名空间
{
<#
foreach (EntityType entity in ItemCollection.GetItems().OrderBy(e => e.Name)) //便利edmx模型中映射的实体对象
{#>    
    public interface I<#=entity.Name#>Dao:IBaseDao<<#=entity.Name#>> //生成实体对象接口
    {
    }
<#};#>
}

 

        3.3 T4模版编辑完成后,Ctrl+s保存,提示是否运行,点击确认。此时就自动帮我们生成了所有的实体类接口,并实现了IBaseDao接口,相应的也具有了CRUD方法定义。

        菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第75张图片         

       菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型_第76张图片

 

你可能感兴趣的:(菜鸟级三层框架(EF+MVC)项目实战之 系列一 EF零基础创建领域模型)