EF的泛型封装 写的很好 转自Fly_Elephant http://www.cnblogs.com/xiaofeixiang/p/4188600.html?utm_source=tuicool

Entity Framework本身的增删改查其实 已经很方便了,不过做项目的时候用的多了也就觉得有点累了,每个业务实体基本上都涉及到到了增删改查这四个基本的要素,至于封装每个公司可能都不一样,接口,设计模式都用的眼花缭乱,我闲来没事就搞个简单的封装Helper,Github上也有关于EF的扩展Libray,具体没有用过,公司的有自己的封装,自己也没怎么弄,具体地址:https://github.com/loresoft/EntityFramework.Extended.

首先来看段代码,model和context是从数据中直接生成,你可以选择自己习惯的方式:

//新增
  User addUser = new User();
  addUser.PersonID = 3;
  addUser.UserName = "keso";
  dbContext.Entry<User>(addUser).State = EntityState.Added;
  dbContext.SaveChanges();
  //修改
  User updateUser = new User();
  dbContext.Users.Where(item => item.ID == 2).OrderBy(item => item.ID);
  updateUser.UserName = updateUser.UserName + "测试";
  dbContext.Entry<User>(updateUser).State = EntityState.Modified;
  dbContext.SaveChanges();
  //删除
  User delUser = dbContext.Users.Where(item => item.ID == 2).First();
  dbContext.Entry<User>(delUser).State = EntityState.Deleted;
  dbContext.SaveChanges();

如果每个业务实体都这么写一遍,估计公司水准有待提高,而且开发的也该跳起来骂人,本人只是简单封装下新建一个EFHelper,实际开发会封装的更多,不过底层处理是不变的

class EFHelpler<T> where T : class
    {
        //...
    }

新增

方法:

/// <summary>
  /// 实体新增
  /// </summary>
  /// <param name="model"></param>
  public void add(params T[] paramList)
  {
      foreach (var model in paramList)
      {
    dbContext.Entry<T>(model).State = EntityState.Added;
      }
      dbContext.SaveChanges();
  }

调用:

EFHelpler<User> helper = new EFHelpler<User>();
      BaseContext dbContext = new BaseContext();
      //新增
      List<User> listUser = new List<User>();
      for (int i = 0; i < 2; i++)
      {
        User user = new User();
        user.PersonID = i;
        user.UserName = "FlyElehant" + i;
        listUser.Add(user);
      }
      helper.add(listUser.ToArray());
      Console.WriteLine("新增成功");

查询

查询分了两种,一种是简单的查询,一种是分页的:

/// <summary>
    /// 实体查询
    /// </summary>
    public IEnumerable<T> getSearchList(System.Linq.Expressions.Expression<Func<T, bool>> where)
    {
      return dbContext.Set<T>().Where(where);
    }
    /// <summary>
    /// 实体分页查询
    /// </summary>
    /// <typeparam name="TKey"></typeparam>
    /// <param name="where"></param>
    /// <param name="orderBy"></param>
    /// <param name="pageSize"></param>
    /// <param name="pageIndex"></param>
    /// <returns></returns>
    public IEnumerable<T> getSearchListByPage<TKey>(Expression<Func<T, bool>> where, Expression<Func<T, TKey>> orderBy, int pageSize, int pageIndex)
    {
      return dbContext.Set<T>().Where(where).OrderByDescending(orderBy).Skip((pageIndex - 1) * pageSize).Take(pageSize);
    }

简单调用,第二个方式除了分页之外,主要是查询的时候指定一定OrderBy的类型,也就是TKey:

var query = helper.getSearchList(item => item.UserName.Contains("keso"));
  var queryMulti = helper.getSearchListByPage<int>(item => item.UserName.Contains("FlyElehant"), order => order.PersonID, 2, 1);
  query = queryMulti;
  foreach (User user in query)
  {
      Console.WriteLine(user.UserName);
  }

修改

修改代码稍微读了几行,主要是用到了一下反射:

/// <summary>
    /// 按照条件修改数据
    /// </summary>
    /// <param name="where"></param>
    /// <param name="dic"></param>
    public void update(Expression<Func<T, bool>> where, Dictionary<string, object> dic)
    {
      IEnumerable<T> result = dbContext.Set<T>().Where(where).ToList();
      Type type = typeof(T);
      List<PropertyInfo> propertyList = type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).ToList();
      //遍历结果集
      foreach (T entity in result)
      {
        foreach (PropertyInfo propertyInfo in propertyList)
        {
          string propertyName = propertyInfo.Name;
          if (dic.ContainsKey(propertyName))
          {
            //设置值
            propertyInfo.SetValue(entity, dic[propertyName], null);
          }
        }
      }
      dbContext.SaveChanges();
    }

调用:

Dictionary<string,object> dic=new Dictionary<string,object>();
            dic.Add("PersonID",2);
            dic.Add("UserName","keso");
            helper.update(item => item.UserName.Contains("keso"), dic);
            Console.WriteLine("修改成功");

删除

方法:

/// <summary>
  /// 实体删除
  /// </summary>
  /// <param name="model"></param>
  public void delete(params T[] paramList)
  {
      foreach (var model in paramList)
      {
    dbContext.Entry<T>(model).State = EntityState.Deleted;
      }
      dbContext.SaveChanges();
  }

调用:

var query = helper.getSearchList(item => item.UserName.Contains("keso"));
            helper.delete(query.ToArray());

完整的EFHelper:

class EFHelpler<T> where T : class
  {
    BaseContext dbContext = new BaseContext();
    /// <summary>
    /// 实体新增
    /// </summary>
    /// <param name="model"></param>
    public void add(params T[] paramList)
    {
      foreach (var model in paramList)
      {
        dbContext.Entry<T>(model).State = EntityState.Added;
      }
      dbContext.SaveChanges();
    }
    /// <summary>
    /// 实体查询
    /// </summary>
    public IEnumerable<T> getSearchList(System.Linq.Expressions.Expression<Func<T, bool>> where)
    {
      return dbContext.Set<T>().Where(where);
    }
    /// <summary>
    /// 实体分页查询
    /// </summary>
    /// <typeparam name="TKey"></typeparam>
    /// <param name="where"></param>
    /// <param name="orderBy"></param>
    /// <param name="pageSize"></param>
    /// <param name="pageIndex"></param>
    /// <returns></returns>
    public IEnumerable<T> getSearchListByPage<TKey>(Expression<Func<T, bool>> where, Expression<Func<T, TKey>> orderBy, int pageSize, int pageIndex)
    {
      return dbContext.Set<T>().Where(where).OrderByDescending(orderBy).Skip((pageIndex - 1) * pageSize).Take(pageSize);
    }
    /// <summary>
    /// 实体删除
    /// </summary>
    /// <param name="model"></param>
    public void delete(params T[] paramList)
    {
      foreach (var model in paramList)
      {
        dbContext.Entry<T>(model).State = EntityState.Deleted;
      }
      dbContext.SaveChanges();
    }
    /// <summary>
    /// 按照条件修改数据
    /// </summary>
    /// <param name="where"></param>
    /// <param name="dic"></param>
    public void update(Expression<Func<T, bool>> where, Dictionary<string, object> dic)
    {
      IEnumerable<T> result = dbContext.Set<T>().Where(where).ToList();
      Type type = typeof(T);
      List<PropertyInfo> propertyList = type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).ToList();
      //遍历结果集
      foreach (T entity in result)
      {
        foreach (PropertyInfo propertyInfo in propertyList)
        {
          string propertyName = propertyInfo.Name;
          if (dic.ContainsKey(propertyName))
          {
            //设置值
            propertyInfo.SetValue(entity, dic[propertyName], null);
          }
        }
      }
      dbContext.SaveChanges();
    }
  }

个人Demo难免有表达不当或者技术失误的地方,如有不当,请多多指出,感激不尽~

时间: 2024-10-28 13:58:19

EF的泛型封装 写的很好 转自Fly_Elephant http://www.cnblogs.com/xiaofeixiang/p/4188600.html?utm_source=tuicool的相关文章

看别人写的优秀代码,是对自己的一种提高,看别人写的很恶心的代码,对自己也是一种提高:告诉自己不要这样写(转)

这两天,我做了两件事: 1.重构了系统某个模块的部分代码: 花了一天时间,一个6k多行的java文件,搞到4k行加若干个类文件,恕我能力有限,后面的实在重构不下去了,那是一种3个domain属性名几乎一样100多个字段但是却用同一个copy了三遍的方法来处理的欲哭无泪,那是一种使劲滚鼠标滚轮都滚不到一个方法尾部的绝望(100多个字段的几个类属性equals来,equals去,get来,set去的,这样类型的方法有那么五六个,你说能不多吗)...... 2.做了一个日志处理的小工具: 客户要求把日

我习惯把代码写得很整齐

我喜欢写C#代码,不喜欢写JS代码和SQL.相比于C#,总感觉JS和SQL写起来乱糟糟的. 最近做了几个统计页面,不得不拼接很长的SQL,我总是尽量把SQL写的层次分明,容易阅读. 应该还有别的实现方法,比如在数据库中写存储过程.函数,但是我不想维护数据库,在当前数据库中没有什么存储过程和函数的情况下,我总是尽量避免在数据库中写存储过程和函数. 别人实现复杂的统计功能的时候,是不是也是这么做的呢?有什么更好的方法? using System; using System.Collections.G

既然写CSS很容易,那为什么大家还是把CSS写的那么烂呢?

在众成翻译上看到一篇不错的css文章,所以就给转过来. 在你开始阅读这篇文章之前,一定要做好心理准备.因为我写的 90% 都是在发牢骚,只有最后大概 10% 介绍 CSS 技巧之最佳实践.提前给你们打好预防针啦. 前端工程师在职业发展中可能会遇到以下困境: 某个阶段,感觉(自己所做的)工作没有任何难度 为团队创造的价值越来越低啦 自己做的事情,大家都能做 同意的请举手.如果你确实是这样,(恭喜你)说明你是多数派. 而且说句实在话,CSS 确实很简单.另外我可以保证,就算是傻子也能写出下面的代码:

.Net利用泛型封装EF CodeFirst 数据库初始值设定项

在使用 EF的code fist 方法我们可能会用到这三个类型对象DropCreateDatabaseAlways(总是删除创建对象) DropCreateDatabaseIfModelChanges(如果对象盖面删除创建对象) CreateDatabaseIfNotExists(如果对象不存在删除创建对象) 今天就利用泛型和工厂模式,将这三个对象封装以下,首先对三个对象类型分别创建子类,便于后期扩展. public class MyDropCreateDatabaseAlways<T> :

DataSet和List&lt;T&gt; 泛型之间互相转换 (转载, 作者写的很好)

/DataSet与泛型集合间的互相转换 //利用反射机制将DataTable的字段与自定义类型的公开属性互相赋值. //注意:从DataSet到IList<T>的转换,自定义类型的公开属性必须与DataTable中的字段名称 //一致,才能到达想要的结果.建议DataTable的定义从数据库来,自定义类型用O/R Mapping的方式获得. //代码说明 /// <summary> /// 泛型集合与DataSet互相转换 /// </summary> using Sy

Entity Framework泛型封装

Entity Framework本身的增删改查其实 已经很方便了,不过做项目的时候用的多了也就觉得有点累了,每个业务实体基本上都涉及到到了增删改查这四个基本的要素,至于封装每个公司可能都不一样,接口,设计模式都用的眼花缭乱,我闲来没事就搞个简单的封装Helper,Github上也有关于EF的扩展Libray,具体没有用过,公司的有自己的封装,自己也没怎么弄,具体地址:https://github.com/loresoft/EntityFramework.Extended. 首先来看段代码,mod

推荐一篇关于java 学习的文章,感觉写的很不错

---恢复内容开始---    很多网友问我学习Java有没有什么捷径,我说"无他,唯手熟尔".但是我却很愿意将自己学习的一些经验写出来,以便后来者少走弯路,帮助别人是最大的快乐嘛!     要想学好Java,首先要知道Java的大致分类.我们知道,自从Sun推出Java以来,就力图使之无所不包,所以Java发展到现在,按应用来分主要分为三块:J2SE,J2ME和J2EE, 这也就是SunONE(OpenNetEnvironment)体系.J2SE就是Java2的标准版,主要用于桌面应

MongoDB 系列(一) C# 类似EF语法简单封装

之前写过一篇关于MongoDB的封装 发现太过繁琐 于是打算从新写一篇简易版 1:关于MongoDB的安装请自行百度,进行权限认证的时候有一个小坑,3.0之后授权认证方式默认的SCRAM-SHA-1模式, 需要首先命令创建一个用户,然后Drop掉这个用户,然后修改system.version里的authScheam为3,在没有创建用户的情况下 authScheam的值貌似是查询不到的. 修改成3后,授权验证方式就变成了MONGODB-CR  2:建立一个聚合根和实体 public interfa

PC游戏编程(入门篇)(前言写的很不错)

PC游戏编程(入门篇) 第一章 基石 1. 1 BOSS登场--GAF简介 第二章 2D图形程式初体验 2.l 饮水思源--第一个"游戏"程式 2.2 知其所以然一一2D图形学基础 2.3 进入图形世界的钥匙--GAFDDraw 2.4 2D图像的本质--图层表面 2.5 场景的秘密--背景卷动 2.6 诱惑--来自"精灵"的问候 2.7 餐后甜点--GAFApp/GAFDDraw的其他法宝 第三章 塞壬的歌声魔力和第三类接触 3.1 1,2,3--计算机音乐概述