关于EF 通用增删改查的封装

1.  Entity Framework是Microsoft的ORM框架,随着 Entity Framework 不断的完善强化已经到达了EF 6.0+ 还是非常的完善的,目前使用的比例相对于其他ORM 的框架还是比较多的。例如有我们目前使用较多的是EF和Drapper 和SQL Sugar 以及NHibernate 当然NHibernate 我使用的不多。当然EF确实使用起来非常的方便开发的速度是比较快的,EF 毕竟在Microsoft 在.NET 体系中已经推出了多年了,无论是成熟度还是其中的性能以及优化的程度都得到了很好很大的改善, 所以还是非常值得我们学习使用,当然我这个不是吹嘘EF 好,而且有的朋友也说了 EF 性能不好效率不高,我想询问一下 针对于这些问题你想过如何进行优化 以及改进没有其实目前改进的方案网上还是非常多的,当然也有很多开发者为EF提供了扩展功能,如Entity Framework  Extended 等里面封装的一些方法就是非常好使用的。而且作为.NET 开发者来说项目的通用性也是非常的强大的,资料也是非常多的,Microsoft在这块的更新力度也很给力。Entity Framework  提供了三种开发模式,Code Frist,Database-First,Model-First。 目前采用Code Frist 的比较多一些 ,但是我建议大家可以使用DB Frist  简单好用。操作方便。当然你如果你喜欢Code Frist 也是拥有自己的好处,反正三者之间 都是相通的,没有什么难点的。都是ORM 之间的转化。

Database-First模式明显性能会差点,非常的适合初学者,或者是比较急的中小型项目一般情况下使用还是足够的。(数据量200W左右还是足够应付的)。

Model-First模式优点是开发人员能够在设计模型时完全了解数据库的结构以及表格之间的关系,但是缺点是在模型设计完后,还是需要去手动创建数据库,而且生成的脚本有点不简洁。

Code-First模式有点不用说了,就是上面两个模式的缺点。缺点应该也是有很多的,比如更新数据库。涉及到数据的迁移这一块。就让大多数人比较头疼。目前解决的方案比较多。

这个这个只是我个人的意见和看法 。所以关于这个EF 的开发模式的如何的使用,决定权利在于你的项目和数据库数据量大小和你公司的目前存在的框架。

2. 关于我个人封装的通用的EF 比较简单好用就是正对于数据库的CRUD ,而且非常适合于单个数据库的读写的操作。 当然你也可以进行对于数据库进行读写分离的操作,建立相互对应的数据库的集群,那么其实说白了 EF本身就是一个对于CRUD 的读写的操作。使用过EF的人知道,EF提供访问数据库的是 DbContext 这个对象,所以想实现读写分离的就很简单了,只要在程序中使用两个不同的DbContext对象,一个负责读,一个负责写就好了。当然你也可以进行使用相对应的工厂化模式进行 读写分离的操作也可以通过 常用的反射来进行读写的操作,决定权取决在你的手上。所以我们在使用其中的读写分离的时候你只管进行对于 DbContext   进行操作就是了 建立相互对于的读写的类就可以了。 一般读写进行分离的都是进行同步于主库的。因为一般情况下的读写的分离 都是一主多从库的模式。

3.在使用这个通用EF CRUD 类的时候需要 进行添加EntityFramework.Extended.6.1.0.168    EntityFramework 6.1.3  两个程序集 。当然 我这里使用的是MySQL 数据库 所以还添加MySQL Data Entity 的等等。添加以上引用的程序集 就可以了。然后还需要添加相对应的Transaction的程序集,这个时候有的朋友就问了 添加Transaction做什么 我的目的就是通过建立想对应的事务来进行回滚 处理简单的并发 要做全部都做,要么全部都不做。如果你采用Queue 来进行解决并发那就更好了。其中关于EF 的CRUD 的通用代码如下。

 using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Data;
using MySql.Data.MySqlClient;
/************************************************
◇作者: LowKeyC
◇说明: 定义一个EF通用的CRUD的接口
◇版本号:V1.0
◇创建日期:2017年6月22日 星期四
*****************************************************/ namespace EFCommon.SqlHelp
{
public interface IRepository : IDisposable
{ /// <summary>
/// 添加实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Entity"></param>
/// <returns></returns>
bool Add<T>(T Entity) where T : class; /// <summary>
/// 批量的进行添加实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Entity"></param>
/// <returns></returns>
bool AddRange<T>(List<T> Entity) where T : class; /// <summary>
/// 删除单个实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Entity"></param>
/// <returns></returns>
bool Delete<T>(T Entity) where T : class; /// <summary>
/// 根据查询条件进行删除单个实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="whereLambda"></param>
/// <returns></returns>
bool Delete<T>(Expression<Func<T, bool>> whereLambda) where T : class; /// <summary>
///单个对象的修改
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Entity">需要修改的对象</param>
/// <returns></returns>
bool Update<T>(T Entity) where T : class; /// <summary>
/// 批量修改
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="whereLambda"></param>
/// <param name="updateLambda"></param>
/// <returns></returns>
bool Update<T>(Expression<Func<T, bool>> WhereLambda, Expression<Func<T, T>> UpdateLambda) where T : class; /// <summary>
/// 批量的修改
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Entity"></param>
/// <returns></returns>
bool Update<T>(List<T> Entity) where T : class; /// <summary>
/// 批量统一的进行更新
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model">需要修改的对象实体</param>
/// <param name="WhereLambda">查询的条件</param>
/// <param name="ModifiedProNames"></param>
/// <returns></returns>
bool Update<T>(T model, Expression<Func<T, bool>> WhereLambda, params string[] ModifiedProNames) where T : class; /// <summary>
/// 根据主键进行查询
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="ID"></param>
/// <returns></returns>
T FindByID<T>(dynamic ID) where T : class; /// <summary>
/// 默认查询选择第一条数据,没有那么进行返回NULL
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="WhereLambda"></param>
/// <returns>返回bool</returns>
T GetFristDefault<T>(Expression<Func<T, bool>> WhereLambda = null) where T : class; /// <summary>
/// 查询所有的数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
List<T> GetAll<T>(string Order = null) where T : class; /// <summary>
/// 含有带条件的查询
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="WhereLambda"></param>
/// <returns></returns>
List<T> GetAllQuery<T>(Expression<Func<T, bool>> WhereLambda = null) where T : class; /// <summary>
///获取查询的数量
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="WhereLambda"></param>
/// <returns></returns>
int GetCount<T>(Expression<Func<T, bool>> WhereLambda = null) where T : class; /// <summary>
/// 判断对象是否存在
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="WhereLambda"></param>
/// <returns></returns>
bool GetAny<T>(Expression<Func<T, bool>> WhereLambda = null) where T : class; /// <summary>
/// 根据查询过条件进行分页
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TKey"></typeparam>
/// <param name="PageIndex">当前页面</param>
/// <param name="PageSize">页面的大小</param>
/// <param name="TotalCount">总记录数</param>
/// <param name="OrderBy">排序的条件</param>
/// <param name="WhereLambda">查询条件</param>
/// <param name="IsOrder">是否正序</param>
/// <returns></returns>
List<T> Pagination<T, TKey>(int PageIndex, int PageSize, out int TotalCount, Expression<Func<T, TKey>> OrderBy, Expression<Func<T, bool>> WhereLambda = null, bool IsOrder = true) where T : class; /// <summary>
/// 根据查询条件进行做分页查询
/// </summary>
/// <typeparam name="T">查询的对象</typeparam>
/// <param name="PageIndex">当前的页码</param>
/// <param name="PageSize">每页的大小</param>
/// <param name="TotalCount">总页数</param>
/// <param name="ordering">排序条件</param>
/// <param name="WhereLambda">查询条件</param>
/// <returns></returns>
List<T> Pagination<T>(int PageIndex, int PageSize, out int TotalCount, string ordering, Expression<Func<T, bool>> WhereLambda = null) where T : class; /// <summary>
/// 根据查询条件进行转化
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="WhereLambda"></param>
/// <returns></returns>
List<T> GetSelect<T>(Expression<Func<T, bool>> WhereLambda) where T : class; /// <summary>
/// 执行存储过程或自定义sql语句--返回集合
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Sql"></param>
/// <param name="Parms"></param>
/// <param name="CmdType"></param>
/// <returns></returns>
List<T> QueryPro<T>(string Sql, List<MySqlParameter> Parms, CommandType CmdType = CommandType.Text) where T : class; /// <summary>
/// 回滚
/// </summary>
/// <typeparam name="T"></typeparam>
void RollBackChanges<T>() where T : class; }
}

4.关于如何实现以上接口的方法。如下面代码所示。当然你也可以将进行实例化对象这里进行采用简单工厂 或者抽象工厂 全凭个人想法。

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Transactions;
using System.Data.Entity;
using System.Linq.Expressions;
using System.Data;
using System.Linq.Dynamic;
using EntityFramework.Extensions;
using System.Reflection;
using System.Data.Entity.Infrastructure;
using MySql.Data.MySqlClient;
/************************************************
◇作者: LowKeyC 需要引用这个程序集:EntityFramework.Extended.6.1.0.168
◇说明: 实现EF通用的CRUD通用的接口
◇版本号:V1.0
◇创建日期:2017年6月22日 星期四
*****************************************************/
namespace EFCommon.SqlHelp
{
public class Repository : IRepository, IDisposable
{ private readonly static DbContext _DbContextHandle =new ahavadbEntities();//此处进行调用EF的DBContent 的实体类或者通过工厂化模式来进行调用。 /// <summary>
/// 添加一个对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Entity"></param>
/// <returns></returns>
public bool Add<T>(T Entity) where T : class
{
using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required))
{
_DbContextHandle.Set<T>().Add(Entity);
int Count = _DbContextHandle.SaveChanges();
Ts.Complete();
return Count > ;
}
} /// <summary>
/// 批量的插入数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Entity"></param>
/// <returns></returns>
public bool AddRange<T>(List<T> Entity) where T : class
{
using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required))
{
_DbContextHandle.Set<T>().AddRange(Entity);
int Count = _DbContextHandle.SaveChanges();
Ts.Complete();
return Count > ;
}
} /// <summary>
/// 根据查询条件进行删除对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="whereLambda">查询条件</param>
/// <returns></returns>
public bool Delete<T>(Expression<Func<T, bool>> whereLambda) where T : class
{
using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required))
{
var EntityModel = _DbContextHandle.Set<T>().Where(whereLambda).FirstOrDefault();
if (EntityModel != null)
{
_DbContextHandle.Set<T>().Remove(EntityModel);
int Count = _DbContextHandle.SaveChanges();
Ts.Complete();
return Count > ;
}
return false;
}
} /// <summary>
/// 删除单个对象的实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Entity">实体对象</param>
/// <returns></returns>
public bool Delete<T>(T Entity) where T : class
{
using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required))
{
_DbContextHandle.Set<T>().Attach(Entity);
_DbContextHandle.Set<T>().Remove(Entity);
int Count = _DbContextHandle.SaveChanges();
Ts.Complete();
return Count > ;
}
} /// <summary>
/// 批量的进行更新数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Entity"></param>
/// <returns></returns>
public bool Update<T>(List<T> Entity) where T : class
{
int Count = ;
using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required))
{
if (Entity != null)
{
foreach (var items in Entity)
{
var EntityModel = _DbContextHandle.Entry(Entity);
_DbContextHandle.Set<T>().Attach(items);
EntityModel.State = EntityState.Modified;
} }
Count = _DbContextHandle.SaveChanges();
Ts.Complete();
} return Count > ;
} /// <summary>
/// 进行修改单个实体对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Entity">实体对象</param>
/// <returns></returns>
public bool Update<T>(T Entity) where T : class
{
using (TransactionScope Ts = new TransactionScope())
{
var EntityModel = _DbContextHandle.Entry<T>(Entity);
_DbContextHandle.Set<T>().Attach(Entity);
EntityModel.State = EntityState.Modified;
int Count = _DbContextHandle.SaveChanges();
Ts.Complete();
return Count > ;
}
} /// <summary>
/// 批量的修改
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="WhereLambda"></param>
/// <param name="UpdateLambda"></param>
/// <returns></returns>
public bool Update<T>(Expression<Func<T, bool>> WhereLambda, Expression<Func<T, T>> UpdateLambda) where T : class
{
_DbContextHandle.Set<T>().Where(WhereLambda).Update<T>(UpdateLambda);
return _DbContextHandle.SaveChanges() > ;
} /// <summary>
/// 查询条件进行修改
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
/// <param name="WhereLambda"></param>
/// <param name="ModifiedProNames"></param>
/// <returns></returns>
public bool Update<T>(T model, Expression<Func<T, bool>> WhereLambda, params string[] ModifiedProNames) where T : class
{
//查询要修改的数据
List<T> ListModifing = _DbContextHandle.Set<T>().Where(WhereLambda).ToList();
Type t = typeof(T);
List<PropertyInfo> ProInfos = t.GetProperties(BindingFlags.Instance | BindingFlags.Public).ToList();
Dictionary<string, PropertyInfo> DitProList = new Dictionary<string, PropertyInfo>();
ProInfos.ForEach(p =>
{
if (ModifiedProNames.Contains(p.Name))
{
DitProList.Add(p.Name, p);
}
}); if (DitProList.Count <= )
{
throw new Exception("指定修改的字段名称有误或为空");
}
foreach (var item in DitProList)
{
PropertyInfo proInfo = item.Value;
object newValue = proInfo.GetValue(model, null);
//批量进行修改相互对应的属性
foreach (T oModel in ListModifing)
{
proInfo.SetValue(oModel, newValue, null);//设置其中新的值
}
} return _DbContextHandle.SaveChanges() > ;
}
/// <summary>
/// 释放缓存
/// </summary>
public void Dispose()
{
_DbContextHandle.Dispose();
} /// <summary>
/// 查询单个对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="ID">主键ID</param>
/// <returns></returns>
public T FindByID<T>(dynamic ID) where T : class
{
return _DbContextHandle.Set<T>().Find(ID) ?? null;
} /// <summary>
/// 获取全部数据的列表
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Order">排序</param>
/// <returns></returns>
public List<T> GetAll<T>(string Order = null) where T : class
{
return Order != null ? _DbContextHandle.Set<T>().OrderBy(Order).ToList() ?? null : _DbContextHandle.Set<T>().ToList() ?? null;
} /// <summary>
///根据查询条件进行查询列表
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="WhereLambda"></param>
/// <returns></returns>
public List<T> GetAllQuery<T>(Expression<Func<T, bool>> WhereLambda = null) where T : class
{
return WhereLambda != null ? _DbContextHandle.Set<T>().Where(WhereLambda).ToList() ?? null : _DbContextHandle.Set<T>().ToList() ?? null;
} /// <summary>
///判断对象是否存在
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="WhereLambda"></param>
/// <returns></returns>
public bool GetAny<T>(Expression<Func<T, bool>> WhereLambda = null) where T : class
{
return WhereLambda != null ? _DbContextHandle.Set<T>().Where(WhereLambda).Any() : _DbContextHandle.Set<T>().Any();
} /// <summary>
/// 获取查询条件的记录数
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="WhereLambda"></param>
/// <returns></returns>
public int GetCount<T>(Expression<Func<T, bool>> WhereLambda = null) where T : class
{
return WhereLambda != null ? _DbContextHandle.Set<T>().Where(WhereLambda).Count() : _DbContextHandle.Set<T>().Count();
} /// <summary>
/// 获取单条的记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="WhereLambda"></param>
/// <returns></returns>
public T GetFristDefault<T>(Expression<Func<T, bool>> WhereLambda = null) where T : class
{
return WhereLambda != null ? _DbContextHandle.Set<T>().Where(WhereLambda).FirstOrDefault() ?? null : _DbContextHandle.Set<T>().FirstOrDefault() ?? null;
} /// <summary>
/// 查询对象的转化
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="WhereLambda"></param>
/// <returns></returns>
public List<T> GetSelect<T>(Expression<Func<T, bool>> WhereLambda) where T : class
{
return _DbContextHandle.Set<T>().Where(WhereLambda).ToList() ?? null;
} /// <summary>
///根据查询条件进行分页
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="PageIndex">当前页</param>
/// <param name="PageSize">每页的大小</param>
/// <param name="TotalCount">总记录数</param>
/// <param name="ordering">排序条件</param>
/// <param name="WhereLambda">查询条件</param>
/// <returns></returns>
public List<T> Pagination<T>(int PageIndex, int PageSize, out int TotalCount, string Ordering, Expression<Func<T, bool>> WhereLambda = null) where T : class
{
//分页的时候一定要注意 Order 一定在Skip 之前
var QueryList = _DbContextHandle.Set<T>().OrderBy(Ordering);
if (WhereLambda != null)
{
QueryList = QueryList.Where(WhereLambda);
} TotalCount = QueryList.Count();
return QueryList.Skip(PageSize * (PageIndex - )).Take(PageSize).ToList() ?? null;
} /// <summary>
///根据查询条件进行分页
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="PageIndex">当前页</param>
/// <param name="PageSize">每页的大小</param>
/// <param name="TotalCount">总记录数</param>
/// <param name="OrderBy">排序条件</param>
/// <param name="WhereLambda">查询的条件</param>
/// <param name="IsOrder"></param>
/// <returns></returns>
public List<T> Pagination<T, TKey>(int PageIndex, int PageSize, out int TotalCount, Expression<Func<T, TKey>> OrderBy, Expression<Func<T, bool>> WhereLambda = null, bool IsOrder = true) where T : class
{
//分页的时候一定要注意 Order一定在Skip 之前
IQueryable<T> QueryList = IsOrder == true ? _DbContextHandle.Set<T>().OrderBy(OrderBy) : _DbContextHandle.Set<T>().OrderByDescending(OrderBy); if (WhereLambda != null)
{
QueryList = QueryList.Where(WhereLambda);
} TotalCount = QueryList.Count();
return QueryList.Skip(PageSize * (PageIndex - )).Take(PageSize).ToList() ?? null;
} /// <summary>
/// 执行存储过程的SQL 语句
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Sql">执行的SQL语句</param>
/// <param name="Parms">SQL 语句的参数</param>
/// <param name="CmdType"></param>
/// <returns></returns>
public List<T> QueryPro<T>(string Sql, List<MySqlParameter> Parms, CommandType CmdType = CommandType.Text) where T : class
{
//进行执行存储过程
if (CmdType == CommandType.StoredProcedure)
{
StringBuilder paraNames = new StringBuilder();
foreach (var item in Parms)
{
paraNames.Append($" @{item},");
}
Sql = paraNames.Length > ? $"exec {Sql} {paraNames.ToString().Trim(',')}" : $"exec {Sql} ";
}
return _DbContextHandle.Set<T>().SqlQuery(Sql, Parms.ToArray()).ToList();
} /// <summary>
/// 进行回滚
/// </summary>
/// <typeparam name="T"></typeparam>
public void RollBackChanges<T>() where T : class
{
var Query = _DbContextHandle.ChangeTracker.Entries().ToList(); Query.ForEach(p => p.State = EntityState.Unchanged);
} }
}

以上内容 全部是基于原创 部分观点 引用了百度百科 以及个人的对于EF 的理解。如需转载请表明!

上一篇:如何用Eclipse创建一个JavaSwing的项目


下一篇:EffectiveJava——用函数对象表示策略