本文例子中使用环境:vs2017,sql server 2008
一,创建EF项目
1,解决方案添加.Net Framework类库项目,在新建的项目下新建项:data->ADO.NET实体数据模型->来自数据库的EF设计器,填写数据库连接,选择包含的内容,完成创建。
二,创建接口及方法封装
此过程可参考文章《关于EF 通用增删改查的封装》,这里复制下代码。
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 { ////// 添加实体 /// /// /// /// bool Add (T Entity) where T : class; /// /// 批量的进行添加实体 /// /// /// /// bool AddRange (List Entity) where T : class; /// /// 删除单个实体 /// /// /// /// bool Delete (T Entity) where T : class; /// /// 根据查询条件进行删除单个实体 /// /// /// /// bool Delete (Expression bool>> whereLambda) where T : class; /// ///单个对象的修改 /// /// /// 需要修改的对象 /// bool Update (T Entity) where T : class; /// /// 批量修改 /// /// /// /// /// bool Update (Expression bool>> WhereLambda, Expression > UpdateLambda) where T : class; /// /// 批量的修改 /// /// /// /// bool Update (List Entity) where T : class; /// /// 批量统一的进行更新 /// /// /// 需要修改的对象实体 /// 查询的条件 /// /// bool Update (T model, Expression bool>> WhereLambda, params string[] ModifiedProNames) where T : class; /// /// 根据主键进行查询 /// /// /// /// T FindByID (dynamic ID) where T : class; /// /// 默认查询选择第一条数据,没有那么进行返回NULL /// /// /// /// 返回bool T GetFristDefault (Expression bool>> WhereLambda = null) where T : class; /// /// 查询所有的数据 /// /// /// List GetAll (string Order = null) where T : class; /// /// 含有带条件的查询 /// /// /// /// List GetAllQuery (Expression bool>> WhereLambda = null) where T : class; /// ///获取查询的数量 /// /// /// /// int GetCount (Expression bool>> WhereLambda = null) where T : class; /// /// 判断对象是否存在 /// /// /// /// bool GetAny (Expression bool>> WhereLambda = null) where T : class; /// /// 根据查询过条件进行分页 /// /// /// /// 当前页面 /// 页面的大小 /// 总记录数 /// 排序的条件 /// 查询条件 /// 是否正序 /// List Pagination (int PageIndex, int PageSize, out int TotalCount, Expression > OrderBy, Expression bool>> WhereLambda = null, bool IsOrder = true) where T : class; /// /// 根据查询条件进行做分页查询 /// /// 查询的对象 /// 当前的页码 /// 每页的大小 /// 总页数 /// 排序条件 /// 查询条件 /// List Pagination (int PageIndex, int PageSize, out int TotalCount, string ordering, Expression bool>> WhereLambda = null) where T : class; /// /// 根据查询条件进行转化 /// /// /// /// List GetSelect (Expression bool>> WhereLambda) where T : class; /// /// 执行存储过程或自定义sql语句--返回集合 /// /// /// /// /// /// List QueryPro (string Sql, List Parms, CommandType CmdType = CommandType.Text) where T : class; /// /// 回滚 /// /// void RollBackChanges () where T : class; } }
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 的实体类或者通过工厂化模式来进行调用。 ////// 添加一个对象 /// /// /// /// public bool Add (T Entity) where T : class { using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required)) { _DbContextHandle.Set ().Add(Entity); int Count = _DbContextHandle.SaveChanges(); Ts.Complete(); return Count > 0; } } /// /// 批量的插入数据 /// /// /// /// public bool AddRange (List Entity) where T : class { using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required)) { _DbContextHandle.Set ().AddRange(Entity); int Count = _DbContextHandle.SaveChanges(); Ts.Complete(); return Count > 0; } } /// /// 根据查询条件进行删除对象 /// /// /// 查询条件 /// public bool Delete (Expression bool>> whereLambda) where T : class { using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required)) { var EntityModel = _DbContextHandle.Set ().Where(whereLambda).FirstOrDefault(); if (EntityModel != null) { _DbContextHandle.Set ().Remove(EntityModel); int Count = _DbContextHandle.SaveChanges(); Ts.Complete(); return Count > 0; } return false; } } /// /// 删除单个对象的实体 /// /// /// 实体对象 /// public bool Delete (T Entity) where T : class { using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required)) { _DbContextHandle.Set ().Attach(Entity); _DbContextHandle.Set ().Remove(Entity); int Count = _DbContextHandle.SaveChanges(); Ts.Complete(); return Count > 0; } } /// /// 批量的进行更新数据 /// /// /// /// public bool Update (List Entity) where T : class { int Count = 0; using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required)) { if (Entity != null) { foreach (var items in Entity) { var EntityModel = _DbContextHandle.Entry(Entity); _DbContextHandle.Set ().Attach(items); EntityModel.State = EntityState.Modified; } } Count = _DbContextHandle.SaveChanges(); Ts.Complete(); } return Count > 0; } /// /// 进行修改单个实体对象 /// /// /// 实体对象 /// public bool Update (T Entity) where T : class { using (TransactionScope Ts = new TransactionScope()) { var EntityModel = _DbContextHandle.Entry (Entity); _DbContextHandle.Set ().Attach(Entity); EntityModel.State = EntityState.Modified; int Count = _DbContextHandle.SaveChanges(); Ts.Complete(); return Count > 0; } } /// /// 批量的修改 /// /// /// /// /// public bool Update (Expression bool>> WhereLambda, Expression > UpdateLambda) where T : class { _DbContextHandle.Set ().Where(WhereLambda).Update (UpdateLambda); return _DbContextHandle.SaveChanges() > 0; } /// /// 查询条件进行修改 /// /// /// /// /// /// public bool Update (T model, Expression bool>> WhereLambda, params string[] ModifiedProNames) where T : class { //查询要修改的数据 List ListModifing = _DbContextHandle.Set ().Where(WhereLambda).ToList(); Type t = typeof(T); List 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 <= 0) { 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() > 0; } /// /// 释放缓存 /// public void Dispose() { _DbContextHandle.Dispose(); } /// /// 查询单个对象 /// /// /// 主键ID /// public T FindByID (dynamic ID) where T : class { return _DbContextHandle.Set ().Find(ID) ?? null; } /// /// 获取全部数据的列表 /// /// /// 排序 /// public List GetAll (string Order = null) where T : class { return Order != null ? _DbContextHandle.Set ().OrderBy(Order).ToList() ?? null : _DbContextHandle.Set ().ToList() ?? null; } /// ///根据查询条件进行查询列表 /// /// /// /// public List GetAllQuery (Expression bool>> WhereLambda = null) where T : class { return WhereLambda != null ? _DbContextHandle.Set ().Where(WhereLambda).ToList() ?? null : _DbContextHandle.Set ().ToList() ?? null; } /// ///判断对象是否存在 /// /// /// /// public bool GetAny (Expression bool>> WhereLambda = null) where T : class { return WhereLambda != null ? _DbContextHandle.Set ().Where(WhereLambda).Any() : _DbContextHandle.Set ().Any(); } /// /// 获取查询条件的记录数 /// /// /// /// public int GetCount (Expression bool>> WhereLambda = null) where T : class { return WhereLambda != null ? _DbContextHandle.Set ().Where(WhereLambda).Count() : _DbContextHandle.Set ().Count(); } /// /// 获取单条的记录 /// /// /// /// public T GetFristDefault (Expression bool>> WhereLambda = null) where T : class { return WhereLambda != null ? _DbContextHandle.Set ().Where(WhereLambda).FirstOrDefault() ?? null : _DbContextHandle.Set ().FirstOrDefault() ?? null; } /// /// 查询对象的转化 /// /// /// /// public List GetSelect (Expression bool>> WhereLambda) where T : class { return _DbContextHandle.Set ().Where(WhereLambda).ToList() ?? null; } /// ///根据查询条件进行分页 /// /// /// 当前页 /// 每页的大小 /// 总记录数 /// 排序条件 /// 查询条件 /// public List Pagination (int PageIndex, int PageSize, out int TotalCount, string Ordering, Expression bool>> WhereLambda = null) where T : class { //分页的时候一定要注意 Order 一定在Skip 之前 var QueryList = _DbContextHandle.Set ().OrderBy(Ordering); if (WhereLambda != null) { QueryList = QueryList.Where(WhereLambda); } TotalCount = QueryList.Count(); return QueryList.Skip(PageSize * (PageIndex - 1)).Take(PageSize).ToList() ?? null; } /// ///根据查询条件进行分页 /// /// /// 当前页 /// 每页的大小 /// 总记录数 /// 排序条件 /// 查询的条件 /// /// public List Pagination (int PageIndex, int PageSize, out int TotalCount, Expression > OrderBy, Expression bool>> WhereLambda = null, bool IsOrder = true) where T : class { //分页的时候一定要注意 Order一定在Skip 之前 IQueryable QueryList = IsOrder == true ? _DbContextHandle.Set ().OrderBy(OrderBy) : _DbContextHandle.Set ().OrderByDescending(OrderBy); if (WhereLambda != null) { QueryList = QueryList.Where(WhereLambda); } TotalCount = QueryList.Count(); return QueryList.Skip(PageSize * (PageIndex - 1)).Take(PageSize).ToList() ?? null; } /// /// 执行存储过程的SQL 语句 /// /// /// 执行的SQL语句 /// SQL 语句的参数 /// /// public List QueryPro (string Sql, List 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 > 0 ? $"exec {Sql} {paraNames.ToString().Trim(',')}" : $"exec {Sql} "; } return _DbContextHandle.Set ().SqlQuery(Sql, Parms.ToArray()).ToList(); } /// /// 进行回滚 /// /// public void RollBackChanges () where T : class { var Query = _DbContextHandle.ChangeTracker.Entries().ToList(); Query.ForEach(p => p.State = EntityState.Unchanged); } } }
因本人使用的是sql server,因此修改这部分的mysql,改用System.Data.SqlClient。采用上面的代码,应该会报错在OrderBy(string),因为构建的是LambdaExpression 类型的,这位大神给出了很好的解决方案,一起去看看吧——c# 扩展方法 奇思妙用 高级篇 九:OrderBy(string propertyName, bool desc)
三,使用注意事项
1,需要把EF的配置拷贝到主程序配置里。
2,在主程序配置中添加entityFramework的节点配置
"System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> "mssqllocaldb"/> "System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
3,在主程序中NuGet包中添加下EntityFramework