支持多条件查询的扩展 ExpressionExtensions.cs类
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace System
{
/// <summary>
/// 谓词表达式构建器
/// </summary>
public static class ExpressionExtensions
{
/// <summary>
/// 创建一个值恒为 <c>true</c> 的表达式。
/// </summary>
/// <typeparam name="T">表达式方法类型</typeparam>
/// <returns>一个值恒为 <c>true</c> 的表达式。</returns>
public static Expression<Func<T, bool>> True<T>() { return p => true; }
/// <summary>
/// 创建一个值恒为 <c>false</c> 的表达式。
/// </summary>
/// <typeparam name="T">表达式方法类型</typeparam>
/// <returns>一个值恒为 <c>false</c> 的表达式。</returns>
public static Expression<Func<T, bool>> False<T>() { return f => false; }
/// <summary>
/// 使用 Expression.OrElse 的方式拼接两个 System.Linq.Expression。
/// </summary>
/// <typeparam name="T">表达式方法类型</typeparam>
/// <param name="left">左边的 System.Linq.Expression 。</param>
/// <param name="right">右边的 System.Linq.Expression。</param>
/// <returns>拼接完成的 System.Linq.Expression。</returns>
public static Expression<T> Or<T>(this Expression<T> left, Expression<T> right)
{
return MakeBinary(left, right, Expression.OrElse);
}
/// <summary>
/// 使用 Expression.AndAlso 的方式拼接两个 System.Linq.Expression。
/// </summary>
/// <typeparam name="T">表达式方法类型</typeparam>
/// <param name="left">左边的 System.Linq.Expression 。</param>
/// <param name="right">右边的 System.Linq.Expression。</param>
/// <returns>拼接完成的 System.Linq.Expression。</returns>
public static Expression<T> And<T>(this Expression<T> left, Expression<T> right)
{
return MakeBinary(left, right, Expression.AndAlso);
}
/// <summary>
/// 使用自定义的方式拼接两个 System.Linq.Expression。
/// </summary>
/// <typeparam name="T">表达式方法类型</typeparam>
/// <param name="left">左边的 System.Linq.Expression 。</param>
/// <param name="right">右边的 System.Linq.Expression。</param>
/// <param name="func"> </param>
/// <returns>拼接完成的 System.Linq.Expression。</returns>
private static Expression<T> MakeBinary<T>(this Expression<T> left, Expression<T> right, Func<Expression, Expression, Expression> func)
{
//Debug.Assert(func != null, "func != null");
return MakeBinary((LambdaExpression)left, right, func) as Expression<T>;
}
/// <summary>
/// 拼接两个 <paramref>
/// <name>System.Linq.Expression</name>
/// </paramref> ,两个 <paramref>
/// <name>System.Linq.Expression</name>
/// </paramref> 的参数必须完全相同。
/// </summary>
/// <param name="left">左边的 <paramref>
/// <name>System.Linq.Expression</name>
/// </paramref> </param>
/// <param name="right">右边的 <paramref>
/// <name>System.Linq.Expression</name>
/// </paramref> </param>
/// <param name="func">表达式拼接的具体逻辑</param>
/// <returns>拼接完成的 <paramref>
/// <name>System.Linq.Expression</name>
/// </paramref> </returns>
private static LambdaExpression MakeBinary(this LambdaExpression left, LambdaExpression right, Func<Expression, Expression, Expression> func)
{
var data = Combinate(right.Parameters, left.Parameters).ToArray();
right = ParameterReplace.Replace(right, data) as LambdaExpression;
//Debug.Assert(right != null, "right != null");
return Expression.Lambda(func(left.Body, right.Body), left.Parameters.ToArray());
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
private static IEnumerable<KeyValuePair<T, T>> Combinate<T>(IEnumerable<T> left, IEnumerable<T> right)
{
var a = left.GetEnumerator();
var b = right.GetEnumerator();
while (a.MoveNext() && b.MoveNext())
yield return new KeyValuePair<T, T>(a.Current, b.Current);
}
}
#region class: ParameterReplace
internal sealed class ParameterReplace : ExpressionVisitor
{
public static Expression Replace(Expression e, IEnumerable<KeyValuePair<ParameterExpression, ParameterExpression>> paramList)
{
var item = new ParameterReplace(paramList);
return item.Visit(e);
}
private readonly Dictionary<ParameterExpression, ParameterExpression> _parameters;
public ParameterReplace(IEnumerable<KeyValuePair<ParameterExpression, ParameterExpression>> paramList)
{
_parameters = paramList.ToDictionary(p => p.Key, p => p.Value, new ParameterEquality());
}
protected override Expression VisitParameter(ParameterExpression p)
{
ParameterExpression result;
if (_parameters.TryGetValue(p, out result))
return result;
return base.VisitParameter(p);
}
#region class: ParameterEquality
private class ParameterEquality : IEqualityComparer<ParameterExpression>
{
public bool Equals(ParameterExpression x, ParameterExpression y)
{
if (x == null || y == null)
return false;
return x.Type == y.Type;
}
public int GetHashCode(ParameterExpression obj)
{
if (obj == null)
return 0;
return obj.Type.GetHashCode();
}
}
#endregion
}
#endregion
}
支持多列排序的封装
IOrderable.cs 接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace ZKHKCMS.IRepository
{
// <summary>
/// 排序规范
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IOrderable<T>
{
/// <summary>
/// 递增
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="keySelector"></param>
/// <returns></returns>
IOrderable<T> Asc<TKey>(global::System.Linq.Expressions.Expression<Func<T, TKey>> keySelector);
/// <summary>
/// 然后递增
/// </summary>
/// <typeparam name="TKey1"></typeparam>
/// <typeparam name="TKey2"></typeparam>
/// <param name="keySelector1"></param>
/// <returns></returns>
IOrderable<T> ThenAsc<TKey>(Expression<Func<T, TKey>> keySelector);
/// <summary>
/// 递减
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="keySelector"></param>
/// <returns></returns>
IOrderable<T> Desc<TKey>(global::System.Linq.Expressions.Expression<Func<T, TKey>> keySelector);
/// <summary>
/// 然后递减
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="keySelector"></param>
/// <returns></returns>
IOrderable<T> ThenDesc<TKey>(Expression<Func<T, TKey>> keySelector);
/// <summary>
/// 排序后的结果集
/// </summary>
global::System.Linq.IQueryable<T> Queryable { get; }
}
}
实现 IOrderable.cs接口的Orderable.cs类
using System;
using System.Linq;
using System.Linq.Expressions;
using ZKHKCMS.IRepository;
namespace ZKHKCMS.Repository
{
/// <summary>
/// Linq架构里对集合排序实现
/// </summary>
/// <typeparam name="T"></typeparam>
public class Orderable<T> : IOrderable<T>
{
private IQueryable<T> _queryable;
/// <summary>
/// 排序后的结果集
/// </summary>
/// <param name="enumerable"></param>
public Orderable(IQueryable<T> enumerable)
{
_queryable = enumerable;
}
/// <summary>
/// 排序之后的结果集
/// </summary>
public IQueryable<T> Queryable
{
get { return _queryable; }
}
/// <summary>
/// 递增
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="keySelector"></param>
/// <returns></returns>
public IOrderable<T> Asc<TKey>(Expression<Func<T, TKey>> keySelector)
{
_queryable = (_queryable as IOrderedQueryable<T>)
.OrderBy(keySelector);
return this;
}
/// <summary>
/// 然后递增
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="keySelector"></param>
/// <returns></returns>
public IOrderable<T> ThenAsc<TKey>(Expression<Func<T, TKey>> keySelector)
{
_queryable = (_queryable as IOrderedQueryable<T>)
.ThenBy(keySelector);
return this;
}
/// <summary>
/// 递减
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="keySelector"></param>
/// <returns></returns>
public IOrderable<T> Desc<TKey>(Expression<Func<T, TKey>> keySelector)
{
_queryable = _queryable
.OrderByDescending(keySelector);
return this;
}
/// <summary>
/// 然后递减
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="keySelector"></param>
/// <returns></returns>
public IOrderable<T> ThenDesc<TKey>(Expression<Func<T, TKey>> keySelector)
{
_queryable = (_queryable as IOrderedQueryable<T>)
.ThenByDescending(keySelector);
return this;
}
}
}
EF通用查询封装
IDAL 接口IBaseRepository.cs
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using ZKHKCMS.Common;
using ZKHKCMS.Models;
namespace ZKHKCMS.IRepository
{
public interface IBaseRepository<T> where T : BaseEntity, new()
{
/// <summary>
/// 新增实体,返回受影响的行数
/// </summary>
/// <param name="model"></param>
/// <returns>返回受影响的行数</returns>
int Add(T model);
/// <summary>
///新增实体,返回对应的实体对象
/// </summary>
/// <param name="model"></param>
/// <returns>新增的实体对象</returns>
T AddReturnModel(T model);
/// <summary>
/// 批量新增实体
/// </summary>
/// <typeparam name="T">泛型类型参数</typeparam>
/// <param name="entityList">待添加的实体集合</param>
/// <returns></returns>
int AddRange(List<T> entityList);
/// <summary>
/// 批量的插入数据(带事务)
/// </summary>
/// <param name="entityList">待添加的实体集合</param>
/// <returns>是否成功插入 true:是 false:否</returns>
bool AddRangeTransaction(List<T> entityList);
/// <summary>
/// 根据id删除数据
/// </summary>
/// <param name="id"></param>
/// <returns>返回受影响的行数</returns>
int DelById(int id);
/// <summary>
/// 根据模型删除数据
/// </summary>
/// <param name="model">该模型对象必须包含id值</param>
/// <returns>返回受影响的行数</returns>
int Delete(T model);
/// <summary>
/// 根据条件删除数据 (支持多条件查询)
/// </summary>
/// <param name="delWhere"></param>
/// <returns>返回受影响的行数</returns>
int Delete(Expression<Func<T, bool>> whereLambda);
/// <summary>
/// 修改实体
/// </summary>
/// <param name="model">该模型对象必须包含id值</param>
/// <returns>返回受影响的行数</returns>
int Edit(T model);
/// <summary>
/// 修改实体,可修改指定属性
/// </summary>
/// <param name="model">该模型对象必须包含id值</param>
/// <param name="propertyName">要修改的属性名称数组</param>
/// <returns></returns>
int Edit(T model, params string[] propertyNames);
/// <summary>
/// 批量修改 (支持多条件查询)
/// </summary>
/// <param name="model"></param>
/// <param name="whereLambda">条件查询表达式</param>
/// <param name="modifiedPropertyNames">要修改的属性名称数组</param>
/// <returns></returns>
int EditBatch(T model, Expression<Func<T, bool>> whereLambda, params string[] modifiedPropertyNames);
/// <summary>
/// 批量修改
/// </summary>
/// <param name="entityList">待修改的实体集合</param>
/// <returns></returns>
int EditBatch(List<T> entityList);
/// <summary>
/// 批量的进行更新数据 (带事务)
/// </summary>
/// <param name="EntityList">待修改的实体集合</param>
/// <returns>是否更新成功 true:是 false:否</returns>
bool EditBatchTransaction(List<T> EntityList);
/// <summary>
/// 根据Id查询单个Model
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
T GetById(int id);
/// <summary>
/// 根据条件查询单个model (支持多条件查询)
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
T Get(Expression<Func<T, bool>> whereLambda);
/// <summary>
/// 根据条件查询单个model (支持多条件查询,支持多列排序)
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="whereLambda">查询条件</param>
/// <param name="orderLambda">排序条件</param>
/// <param name="isAsc"></param>
/// <returns></returns>
T Get(Expression<Func<T, bool>> whereLambda, Action<IOrderable<T>> orderBy = null);
/// <summary>
/// 根据条件查询单个model (支持多条件查询,仅支持单列排序)
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="whereLambda">查询条件</param>
/// <param name="orderLambda">排序条件</param>
/// <param name="isAsc">是否为升序排序,默认true</param>
/// <returns></returns>
T Get<TKey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderByLambda, bool isAsc = true);
/// <summary>
/// 查询所有数据
/// </summary>
/// <returns></returns>
IQueryable<T> GetAll();
/// <summary>
/// 获取查询条件的数据总条数 (支持多条件查询)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="whereLambda"></param>
/// <returns></returns>
int GetCount(Expression<Func<T, bool>> whereLambda = null);
/// <summary>
/// 判断对象是否存在 (支持多条件查询)
/// </summary>
/// <param name="whereLambda">查询条件</param>
/// <returns>对象存在则返回true,不存在则返回false</returns>
bool GetAny(Expression<Func<T, bool>> whereLambda = null);
/// <summary>
/// 获取数据集合 (支持多条件查询)
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
IQueryable<T> GetList(Expression<Func<T, bool>> whereLambda);
/// <summary>
/// 获取数据集合 (支持多条件查询,仅支持单条件排序)
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="whereLambda"></param>
/// <param name="orderLambda"></param>
/// <param name="isAsc">是否为升序排序,默认为true</param>
/// <returns></returns>
IQueryable<T> GetList<TKey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderByLambda, bool isAsc = true);
/// <summary>
/// 获取数据集合 (支持多条件查询,支持多列排序)
/// </summary>
/// <param name="whereLambda"></param>
/// <param name="orderBy"></param>
/// <returns></returns>
IQueryable<T> GetList(Expression<Func<T, bool>> whereLambda, Action<IOrderable<T>> orderBy);
/// <summary>
/// 获取数据集合 (支持多条件查询,支持多列排序)
/// </summary>
/// <typeparam name="E">目标类型:说明:将查询出来的数据转换成目标类型实体</typeparam>
/// <param name="orderBy">排序(可选)</param>
/// <returns></returns>
IQueryable<E> GetList<E>(string sql, Action<IOrderable<E>> orderBy = null);
/// <summary>
/// 分页查询 (支持多条件查询,仅支持单列排序)
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="pageIndex">当前页</param>
/// <param name="pageSize">每页显示数据的条数</param>
/// <param name="whereLambda">查询条件</param>
/// <param name="orderByLambda">排序条件</param>
/// <param name="isAsc">是否为升序排序,默认为true</param>
/// <returns></returns>
IQueryable<T> GetPagedList<TKey>(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderByLambda, bool isAsc = true);
/// <summary>
/// 分页查询 ,带输出数据总条数 (支持多条件查询,仅支持单列排序)
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="pageIndex">当前页</param>
/// <param name="pageSize">每页显示数据的条数</param>
/// <param name="totalCount">数据总条数</param>
/// <param name="orderByLambda">排序条件</param>
/// <param name="whereLambda">查询条件</param>
/// <param name="isAsc">是否为升序排序,默认为true</param>
/// <returns></returns>
IQueryable<T> GetPagedList<TKey>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, TKey>> orderByLambda, Expression<Func<T, bool>> whereLambda = null, bool isAsc = true);
/// <summary>
/// 分页查询,带输出数据总条数 (支持多条件查询,支持多列排序)
/// </summary>
/// <param name="pageIndex">当前页</param>
/// <param name="pageSize">每页显示数据的条数</param>
/// <param name="totalCount">输出数据:数据总条数</param>
/// <param name="whereLambda">查询条件</param>
/// <param name="orderBy">排序条件</param>
/// <returns></returns>
IQueryable<T> GetPagedList(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> whereLambda = null, Action<IOrderable<T>> orderBy = null);
/// <summary>
/// 执行存储过程的SQL 语句
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Sql">执行的SQL语句</param>
/// <param name="Parms">SQL 语句的参数</param>
/// <param name="CmdType"> SQL命令(默认为Text)</param>
/// <returns></returns>
IQueryable<T> ProQuery(string Sql, List<SqlParameter> Parms, CommandType CmdType = CommandType.Text);
/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回给定泛型类型的元素。
/// </summary>
/// <typeparam name="T">查询所返回对象的类型</typeparam>
/// <param name="sql">SQL 查询字符串</param>
/// <param name="parameters">要应用于 SQL 查询字符串的参数</param>
/// <returns></returns>
IQueryable<T> SqlQuery(string sql, params SqlParameter[] parameters);
/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回给定泛型类型的元素 (用于MySql数据库,需要安装MySql.Data插件)
/// </summary>
/// <typeparam name="T">查询所返回对象的类型</typeparam>
/// <param name="sql">SQL 查询字符串</param>
/// <param name="parameters">要应用于 SQL 查询字符串的参数</param>
/// <returns></returns>
IQueryable<T> MySqlQuery(string sql, params MySqlParameter[] parameters);
/// <summary>
/// 创建一个原始 SQL 用户 新增,删除,编辑
/// </summary>
/// <param name="sql"></param>
/// <param name="parameters"></param>
/// <returns>返回受影响的行数</returns>
int ExecuteSqlCommand(string sql, params SqlParameter[] parameters);
/// <summary>
/// 创建一个原始 SQL 用户 新增,删除,编辑 (用于MySql数据库,需要安装MySql.Data插件)
/// </summary>
/// <param name="sql"></param>
/// <param name="parameters"></param>
/// <returns>返回受影响的行数</returns>
int ExecuteMySqlCommand(string sql, params MySqlParameter[] parameters);
/// <summary>
/// 获取带 in 的sql参数列表
/// </summary>
/// <param name="sql">带in ( {0} )的sql</param>
/// <param name="ids">以逗号分隔的id字符串</param>
/// <returns>sql参数列表</returns>
SqlParameter[] GetWithInSqlParameters(ref string sql, string ids);
}
}
DAL 类 BaseRepository.cs
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Transactions;
using ZKHKCMS.Common;
using ZKHKCMS.Entities;
using ZKHKCMS.IRepository;
using ZKHKCMS.Models;
namespace ZKHKCMS.Repository
{
public class BaseRepository<T> : IBaseRepository<T> where T : BaseEntity, new()
{
DbContext db = DBContextFactory.GetCurrentObjectContext();
/// <summary>
/// 新增实体,返回受影响的行数
/// </summary>
/// <param name="model"></param>
/// <returns>返回受影响的行数</returns>
public int Add(T model)
{
db.Set<T>().Add(model);
return db.SaveChanges();
}
/// <summary>
///新增实体,返回对应的实体对象
/// </summary>
/// <param name="model"></param>
/// <returns>新增的实体对象</returns>
public T AddReturnModel(T model)
{
db.Set<T>().Add(model);
db.SaveChanges();
return model;
}
/// <summary>
/// 批量新增实体
/// </summary>
/// <typeparam name="T">泛型类型参数</typeparam>
/// <param name="entityList">待添加的实体集合</param>
/// <returns></returns>
public int AddRange(List<T> entityList)
{
db.Set<T>().AddRange(entityList);
return db.SaveChanges();
}
/// <summary>
/// 批量的新增实体(带事务)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Entity"></param>
/// <returns></returns>
public bool AddRangeTransaction(List<T> entityList)
{
using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required))
{
db.Set<T>().AddRange(entityList);
int Count = db.SaveChanges();
Ts.Complete();
return Count > 0;
}
}
/// <summary>
/// 根据id删除数据
/// </summary>
/// <param name="id"></param>
/// <returns>返回受影响的行数</returns>
public int DelById(int id)
{
var model = GetById(id);
if (model == null || model.id <= 0) return -1;
db.Set<T>().Remove(model);
return db.SaveChanges();
}
/// <summary>
/// 根据模型删除数据
/// </summary>
/// <param name="model">该模型对象必须包含id值</param>
/// <returns>返回受影响的行数</returns>
public int Delete(T model)
{
db.Set<T>().Attach(model);
db.Set<T>().Remove(model);
return db.SaveChanges();
}
/// <summary>
/// 根据条件删除数据 (支持多条件查询)
/// </summary>
/// <param name="delWhere"></param>
/// <returns>返回受影响的行数</returns>
public int Delete(Expression<Func<T, bool>> whereLambda)
{
//查询要删除的数据
List<T> listDeleting = db.Set<T>().Where(whereLambda).ToList();
//将要删除的数据 用删除方法添加到 EF 容器中
listDeleting.ForEach(u =>
{
db.Set<T>().Attach(u); //先附加到EF 容器
db.Set<T>().Remove(u); //标识为删除状态
});
return db.SaveChanges();
}
/// <summary>
/// 修改实体
/// </summary>
/// <param name="model">该模型对象必须包含id值</param>
/// <returns>返回受影响的行数</returns>
public int Edit(T model)
{
DbEntityEntry entry = db.Entry<T>(model);
entry.State = EntityState.Modified;
return db.SaveChanges();
}
/// <summary>
/// 修改实体,可修改指定属性
/// </summary>
/// <param name="model">该模型对象必须包含id值</param>
/// <param name="propertyName">要修改的属性名称数组</param>
/// <returns></returns>
public int Edit(T model, params string[] propertyNames)
{
DbEntityEntry entry = db.Entry<T>(model); //将对象添加到EF中
entry.State = EntityState.Unchanged; //先设置对象的包装状态为 Unchanged
foreach (string propertyName in propertyNames) //循环被修改的属性名数组
{
//将每个被修改的属性的状态设置为已修改状态;这样在后面生成的修改语句时,就只为标识为已修改的属性更新
entry.Property(propertyName).IsModified = true;
}
return db.SaveChanges();
}
/// <summary>
/// 批量修改 (支持多条件查询)
/// </summary>
/// <param name="model"></param>
/// <param name="whereLambda"></param>
/// <param name="modifiedPropertyNames"></param>
/// <returns></returns>
public int EditBatch(T model, Expression<Func<T, bool>> whereLambda, params string[] modifiedPropertyNames)
{
List<T> listModifing = db.Set<T>().Where(whereLambda).ToList(); //查询要修改的数据
Type t = typeof(T); //获取实体类类型对象
List<PropertyInfo> propertyInfos = t.GetProperties(BindingFlags.Instance | BindingFlags.Public).ToList();//获取实体类所有的公共属性
Dictionary<string, PropertyInfo> dicPropertys = new Dictionary<string, PropertyInfo>(); //创建实体属性字典集合
//将实体属性中要修改的属性名 添加到字典集合中 键:属性名 值:属性对象
propertyInfos.ForEach(p =>
{
if (modifiedPropertyNames.Contains(p.Name))
{
dicPropertys.Add(p.Name, p);
}
});
foreach (string propertyName in modifiedPropertyNames)//循环要修改的属性名
{
if (dicPropertys.ContainsKey(propertyName)) //判断要修改的属性名是否在实体类的属性集合中存在
{
PropertyInfo proInfo = dicPropertys[propertyName];//如果存在,则取出要修改的属性对象
object newValue = proInfo.GetValue(model, null);//取出要修改的值
foreach (T item in listModifing) //批量设置要修改对象的属性
{
proInfo.SetValue(item, newValue, null);// 为要修改的对象的要修改的属性设置新的值
}
}
}
return db.SaveChanges();
}
/// <summary>
/// 批量修改
/// </summary>
/// <param name="models"></param>
/// <returns></returns>
public int EditBatch(List<T> entityList)
{
foreach (var entity in entityList)
{
DbEntityEntry entry = db.Entry(entity);
entry.State = EntityState.Modified;
}
return db.SaveChanges();
}
/// <summary>
/// 批量的进行更新数据 (带事务)
/// </summary>
/// <param name="Entity"></param>
/// <returns></returns>
public bool EditBatchTransaction(List<T> EntityList)
{
int Count = 0;
using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required))
{
if (EntityList != null)
{
foreach (var items in EntityList)
{
var EntityModel = db.Entry(EntityList);
db.Set<T>().Attach(items);
EntityModel.State = EntityState.Modified;
}
}
Count = db.SaveChanges();
Ts.Complete();
}
return Count > 0;
}
/// <summary>
/// 根据Id查询单个Model
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public T GetById(int id)
{
return db.Set<T>().FirstOrDefault(r => r.id == id);
}
/// <summary>
/// 根据条件查询单个model (支持多条件查询)
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public T Get(Expression<Func<T, bool>> whereLambda)
{
return db.Set<T>().Where(whereLambda).FirstOrDefault();
}
/// <summary>
/// 根据条件查询单个model (支持多条件查询,支持多列排序)
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="whereLambda">查询条件</param>
/// <param name="orderLambda">排序条件</param>
/// <param name="isAsc"></param>
/// <returns></returns>
public T Get(Expression<Func<T, bool>> whereLambda, Action<IOrderable<T>> orderBy = null)
{
IQueryable<T> QueryList = db.Set<T>();
if (whereLambda != null)
{
QueryList = QueryList.Where(whereLambda);
}
if (orderBy != null)
{
var linq = new Orderable<T>(QueryList);
orderBy(linq);
return linq.Queryable.FirstOrDefault();
}
return QueryList.FirstOrDefault();
}
/// <summary>
/// 根据条件查询单个model (支持多条件查询,仅支持单列排序)
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="whereLambda">查询条件</param>
/// <param name="orderLambda">排序条件</param>
/// <param name="isAsc">是否为升序排序,默认true</param>
/// <returns></returns>
public T Get<TKey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderByLambda, bool isAsc = true)
{
IQueryable<T> Query = isAsc == true ? db.Set<T>().OrderBy(orderByLambda) : db.Set<T>().OrderByDescending(orderByLambda);
if (whereLambda != null)
{
Query = Query.Where(whereLambda);
}
return Query.FirstOrDefault();
}
/// <summary>
/// 查询所有数据
/// </summary>
/// <returns></returns>
public IQueryable<T> GetAll()
{
return db.Set<T>();
}
/// <summary>
/// 获取查询条件的数据总条数 (支持多条件查询)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="whereLambda"></param>
/// <returns></returns>
public int GetCount(Expression<Func<T, bool>> whereLambda = null)
{
return whereLambda != null ? db.Set<T>().Where(whereLambda).Count() : db.Set<T>().Count();
}
/// <summary>
/// 判断对象是否存在 (支持多条件查询)
/// </summary>
/// <param name="whereLambda">查询条件</param>
/// <returns>对象存在则返回true,不存在则返回false</returns>
public bool GetAny(Expression<Func<T, bool>> whereLambda = null)
{
return whereLambda != null ? db.Set<T>().Where(whereLambda).Any() : db.Set<T>().Any();
}
/// <summary>
/// 获取数据集合 (支持多条件查询)
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public IQueryable<T> GetList(Expression<Func<T, bool>> whereLambda)
{
return db.Set<T>().Where(whereLambda);
}
/// <summary>
/// 获取数据集合 (支持多条件查询,仅支持单条件排序)
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="whereLambda"></param>
/// <param name="orderLambda"></param>
/// <param name="isAsc">是否为升序排序,默认为true</param>
/// <returns></returns>
public IQueryable<T> GetList<TKey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderByLambda, bool isAsc = true)
{
IQueryable<T> QueryList = isAsc == true ? db.Set<T>().OrderBy(orderByLambda) : db.Set<T>().OrderByDescending(orderByLambda);
if (whereLambda != null)
{
QueryList = QueryList.Where(whereLambda);
}
return QueryList;
}
/// <summary>
/// 获取数据集合 (支持多条件查询,支持多列排序)
/// </summary>
/// <param name="whereLambda"></param>
/// <param name="orderBy"></param>
/// <returns></returns>
public IQueryable<T> GetList(Expression<Func<T, bool>> whereLambda, Action<IOrderable<T>> orderBy)
{
IQueryable<T> QueryList = db.Set<T>();
if (whereLambda != null)
{
QueryList = QueryList.Where(whereLambda);
}
var linq = new Orderable<T>(QueryList);
orderBy(linq);
return linq.Queryable;
}
/// <summary>
/// 获取数据集合 (支持多条件查询,支持多列排序)
/// </summary>
/// <typeparam name="Entity">目标类型:说明:将查询出来的数据转换成目标类型实体</typeparam>
/// <param name="orderBy">排序(可选)</param>
/// <returns></returns>
public IQueryable<E> GetList<E>(string sql, Action<IOrderable<E>> orderBy = null)
{
IQueryable<E> QueryList = db.Database.SqlQuery<E>(sql).AsQueryable();
if (orderBy != null)
{
var linq = new Orderable<E>(QueryList);
orderBy(linq);
return linq.Queryable;
}
return QueryList;
}
/// <summary>
/// 分页查询 (支持多条件查询,仅支持单列排序)
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="pageIndex">当前页</param>
/// <param name="pageSize">每页显示数据的条数</param>
/// <param name="whereLambda">查询条件</param>
/// <param name="orderByLambda">排序条件</param>
/// <param name="isAsc">是否为升序排序,默认为true</param>
/// <returns></returns>
public IQueryable<T> GetPagedList<TKey>(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderByLambda, bool isAsc = true)
{
//分页的时候一定要注意 Order一定在Skip 之前
IQueryable<T> QueryList = isAsc == true ? db.Set<T>().OrderBy(orderByLambda) : db.Set<T>().OrderByDescending(orderByLambda);
if (whereLambda != null)
{
QueryList = QueryList.Where(whereLambda);
}
return QueryList.Skip(pageSize * (pageIndex - 1)).Take(pageSize);
}
/// <summary>
/// 分页查询 ,带输出数据总条数 (支持多条件查询,仅支持单列排序)
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="pageIndex">当前页</param>
/// <param name="pageSize">每页显示数据的条数</param>
/// <param name="totalCount">数据总条数</param>
/// <param name="orderByLambda">排序条件</param>
/// <param name="whereLambda">查询条件</param>
/// <param name="isAsc">是否为升序排序,默认为true</param>
/// <returns></returns>
public IQueryable<T> GetPagedList<TKey>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, TKey>> orderByLambda, Expression<Func<T, bool>> whereLambda = null, bool isAsc = true)
{
//分页的时候一定要注意 Order一定在Skip 之前
IQueryable<T> QueryList = isAsc == true ? db.Set<T>().OrderBy(orderByLambda) : db.Set<T>().OrderByDescending(orderByLambda);
if (whereLambda != null)
{
QueryList = QueryList.Where(whereLambda);
}
totalCount = QueryList.Count();
return QueryList.Skip(pageSize * (pageIndex - 1)).Take(pageSize);
}
/// <summary>
/// 分页查询,带输出数据总条数 (支持多条件查询,支持多列排序)
/// </summary>
/// <param name="pageIndex">当前页</param>
/// <param name="pageSize">每页显示数据的条数</param>
/// <param name="totalCount">输出数据:数据总条数</param>
/// <param name="whereLambda">查询条件</param>
/// <param name="orderBy">排序条件</param>
/// <returns></returns>
public IQueryable<T> GetPagedList(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> whereLambda = null, Action<IOrderable<T>> orderBy = null)
{
IQueryable<T> QueryList = db.Set<T>();
if (whereLambda != null)
{
QueryList = QueryList.Where(whereLambda);
}
totalCount = QueryList.Count();
if (orderBy != null)
{
var linq = new Orderable<T>(QueryList);
orderBy(linq);
return linq.Queryable.Skip(pageSize * (pageIndex - 1)).Take(pageSize);
}
return QueryList.Skip(pageSize * (pageIndex - 1)).Take(pageSize); ;
}
/// <summary>
/// 执行存储过程的SQL 语句
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Sql">执行的SQL语句</param>
/// <param name="Parms">SQL 语句的参数</param>
/// <param name="CmdType"> SQL命令(默认为Text)</param>
/// <returns></returns>
public IQueryable<T> ProQuery(string Sql, List<SqlParameter> Parms, CommandType CmdType = CommandType.Text)
{
//进行执行存储过程
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 db.Set<T>().SqlQuery(Sql, Parms.ToArray()).AsQueryable();
}
/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回给定泛型类型的元素
/// </summary>
/// <typeparam name="T">查询所返回对象的类型</typeparam>
/// <param name="sql">SQL 查询字符串</param>
/// <param name="parameters">要应用于 SQL 查询字符串的参数</param>
/// <returns></returns>
public IQueryable<T> SqlQuery(string sql, params SqlParameter[] parameters)
{
return db.Database.SqlQuery<T>(sql, parameters).AsQueryable();
}
/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回给定泛型类型的元素 (用于MySql数据库,需要安装MySql.Data插件)
/// </summary>
/// <typeparam name="T">查询所返回对象的类型</typeparam>
/// <param name="sql">SQL 查询字符串</param>
/// <param name="parameters">要应用于 SQL 查询字符串的参数</param>
/// <returns></returns>
public IQueryable<T> MySqlQuery(string sql, params MySqlParameter[] parameters)
{
return db.Database.SqlQuery<T>(sql, parameters).AsQueryable();
}
/// <summary>
/// 创建一个原始 SQL 用户 新增,删除,编辑
/// </summary>
/// <param name="sql"></param>
/// <param name="parameters"></param>
/// <returns>返回受影响的行数</returns>
public int ExecuteSqlCommand(string sql, params SqlParameter[] parameters)
{
return db.Database.ExecuteSqlCommand(sql, parameters);
}
/// <summary>
/// 创建一个原始 SQL 用户 新增,删除,编辑 (用于MySql数据库,需要安装MySql.Data插件)
/// </summary>
/// <param name="sql"></param>
/// <param name="parameters"></param>
/// <returns>返回受影响的行数</returns>
public int ExecuteMySqlCommand(string sql, params MySqlParameter[] parameters)
{
return db.Database.ExecuteSqlCommand(sql, parameters);
}
/// <summary>
/// 获取带 in 的sql参数列表
/// </summary>
/// <param name="sql">带in ( {0} )的sql</param>
/// <param name="ids">以逗号分隔的id字符串</param>
/// <returns>sql参数列表</returns>
public SqlParameter[] GetWithInSqlParameters(ref string sql, string ids)
{
if (string.IsNullOrEmpty(ids))
{
return null;
}
string[] idArr = ids.Split(',');
//组建sql在in中的字符串
StringBuilder sbCondition = new StringBuilder();
List<SqlParameter> spList = new List<SqlParameter>();
for (int i = 0; i < idArr.Length; i++)
{
string id = idArr[i];
sbCondition.Append("@id" + i + ",");
spList.Add(new SqlParameter("@id" + i.ToString(), id));
}
//重新构建sql
sql = string.Format(sql, sbCondition.ToString().TrimEnd(','));
return spList.ToArray();
}
}
}
控制器中调用示例--(多条件查询,多列排序示例)
/// <summary>
/// 菜单
/// </summary>
public class MenuController : BaseController
{
public IMenuRepository menu { get; set; } /IOC属性注入
/// <summary>
/// 分页查询
/// </summary>
/// <param name="pageIndex">当前页</param>
/// <param name="menuName">菜单名称</param>
/// <param name="menuLevel">菜单级别</param>
/// <returns></returns>
[HttpPost]
public JsonResult List(int pageIndex, int pageSize, string menuName,int menuLevel)
{
Expression<Func<Menu, bool>> filter = r => true;
if (!string.IsNullOrEmpty(menuName))//条件查询一
{
filter = filter.And(r => r.MenuName.Contains(menuName));
}
if (menuLevel > 0)//条件查询二
{
filter = filter.And(r => r.MenuLevel == menuLevel);
}
//先对sort列进行升序排序,然后对menuParentId列进行降序排序 (定义排序条件)
Action<IOrderable<Menu>> orderBy = query => query.Asc(j => j.sort).ThenDesc(k => k.menuParentId);
var totalCount=0;
var data = menu.GetPagedList(pageIndex, pageSize,ref totalCount, filter, orderBy); //调用分页方法(根据多条件查询,根据多列排序)
var result = new { TotalCount = totalCount, Data = data.ToList() }; //返回数据
return Success(result);
}
}
附送获取EF上下文对象实例 DBContextFactory.cs类
using System.Data.Entity;
using System.Runtime.Remoting.Messaging;
namespace ZKHKCMS.Entities
{
public class DBContextFactory
{
/// <summary>
/// 获取EF上下文容器类对象实例
/// </summary>
/// <returns></returns>
public static DbContext GetCurrentObjectContext()
{
//从CallContext数据槽中获取EF上下文
DbContext objectContext = CallContext.GetData(typeof(DBContextFactory).FullName) as DbContext;
if (objectContext == null)
{
//如果CallContext数据槽中没有EF上下文,则创建EF上下文,并保存到CallContext数据槽中
objectContext = new HKEntitiesDbContext();//当数据库替换为MySql等,只要在此处EF更换上下文即可。这里的DBContent是model.context.cs中的局部类
CallContext.SetData(typeof(DBContextFactory).FullName, objectContext);
}
return objectContext;
}
//public static DbContext GetCurrentContext() //写法二
//{
// //CallContext:保证线程内创建的数据操作上下文是唯一的。
// DbContext DbContext = (DbContext)CallContext.GetData("context");
// if (DbContext == null)
// {
// DbContext = new HKEntitiesDbContext();
// CallContext.SetData("context", DbContext);
// }
// return DbContext;
//}
}
}