zoukankan      html  css  js  c++  java
  • 菜鸟级三层框架(EF+MVC)项目实战之 系列二 对数据访问层的抽象中

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

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

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

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

              

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

             

          1.3 添加如下引用

              

    二、创建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中定义方法,用于所有实体类继承此基类。

               

         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<T>
     12                  where T:class,
     13                  new()
     14                     
     15    {
     16        ObjectContext objectContext= ObjectContextFactory.GetCurrentObjectContext() as ObjectContext;//获取EF上下文
     17 
     18        /// <summary>
     19        /// 加载实体集合
     20        /// </summary>
     21        /// <param name="whereLambda"></param>
     22        /// <returns></returns>
     23        public virtual IQueryable<T> LoadEntites(Func<T,bool> whereLambda)
     24        {
     25           return objectContext.CreateObjectSet<T>().Where<T>(whereLambda).AsQueryable<T>();
     26        }
     27 
     28        /// <summary>
     29        /// 分页加载数据
     30        /// </summary>
     31        /// <param name="whereLambda">过滤条件</param>
     32        /// <param name="pageIndex">页码</param>
     33        /// <param name="pageSize">页大小</param>
     34        /// <param name="totalCount">总记录数</param>
     35        /// <returns></returns>
     36        public virtual IQueryable<T> LoadEntites(Func<T,bool> whereLambda, int pageIndex, int pageSize, out int totalCount)
     37        {
     38           var tmp= objectContext.CreateObjectSet<T>().Where<T>(whereLambda);
     39           totalCount = tmp.Count();
     40 
     41           return tmp.Skip<T>(pageSize * (pageIndex - 1))//跳过行数,最终生成的sql语句是Top(n)
     42                     .Take<T>(pageSize) //返回指定数量的行
     43                     .AsQueryable<T>();
     44        }
     45 
     46        /// <summary>
     47        /// 添加实体
     48        /// </summary>
     49        /// <param name="entity"></param>
     50        /// <returns>返回更新后的实体</returns>
     51        public virtual T AddEntity(T entity)
     52        {
     53            objectContext.CreateObjectSet<T>().AddObject(entity);
     54            objectContext.SaveChanges();
     55            return entity;
     56        }
     57 
     58        /// <summary>
     59        /// 更新实体
     60        /// </summary>
     61        /// <param name="entity"></param>
     62        /// <returns>返回更新后的实体</returns>
     63        public virtual T UpdateEntity(T entity)
     64        {
     65            objectContext.CreateObjectSet<T>().Attach(entity);
     66            objectContext.ObjectStateManager.ChangeObjectState(entity, System.Data.EntityState.Modified);//将附加的对象状态更改为修改
     67            objectContext.SaveChanges();
     68            return entity;
     69        }
     70 
     71        /// <summary>
     72        /// 删除实体
     73        /// </summary>
     74        /// <param name="entity"></param>
     75        /// <returns></returns>
     76        public virtual bool DelEntity(T entity)
     77        {
     78            objectContext.CreateObjectSet<T>().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        /// <summary>
     91        /// 根据条件删除对象
     92        /// </summary>
     93        /// <param name="whereLambda">条件</param>
     94        /// <returns></returns>
     95        public virtual bool DelEntityByWhere(Func<T, bool> whereLambda)
     96        {
     97           var tmp= objectContext.CreateObjectSet<T>().Where<T>(whereLambda);//根据条件从数据库中获取对象集合
     98           foreach (var entity in tmp)
     99           {
    100               objectContext.CreateObjectSet<T>().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<EntityType>().OrderBy(e => e.Name))
    {#>    
        public partial class <#=entity.Name#>Dao:BaseDao<<#=entity.Name#>>,I<#=entity.Name#>Dao
        {
          
        }
    <#};#>
    }

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

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

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

  • 相关阅读:
    poj 3068 Bridge Across Islands
    XidianOJ 1086 Flappy v8
    XidianOJ 1036 分配宝藏
    XidianOJ 1090 爬树的V8
    XidianOJ 1088 AK后的V8
    XidianOJ 1062 Black King Bar
    XidianOJ 1091 看Dota视频的V8
    XidianOJ 1098 突击数论前的xry111
    XidianOJ 1019 自然数的秘密
    XidianOJ 1109 Too Naive
  • 原文地址:https://www.cnblogs.com/rdst/p/2635077.html
Copyright © 2011-2022 走看看