聲明
這里有此東西是參考各大神修改和補充而來,有些地方就找不到原文章的地址了,一參考地址如下:
http://www.cnblogs.com/ahui/archive/2011/08/04/2127282.html
寄語
本着取之於大神,還之於大眾的精神,我把本人整理以及擴展的一些重要部分貼出來,希望你也積極把你覺得好的擴展回應到此貼中。
1、ExecuteSqlCommand和SqlQuery擴展
作用:擴展后省去寫大堆的new SqlParameter了

#region 動態執行Sql語句擴展 /// <summary> /// 根據sql語句和參數的值動態生成Sqlparameter /// </summary> /// <param name="sql">sql語句</param> /// <param name="values">值</param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException"></exception> /// <returns></returns> private static SqlParameter[] MakeSqlParameter(string sql, object[] values) { var matches = Regex.Matches(sql, @"@\w+"); List<string> paramNameList = new List<string>(); foreach (Match m in matches) { if (paramNameList.Contains(m.Value) == false) { paramNameList.Add(m.Value); } } if (values.Length != paramNameList.Count) { throw new ArgumentException("values的元素數目和Sql語句不匹配"); } int i = 0; var parameters = new SqlParameter[values.Length]; foreach (var pName in paramNameList) { parameters[i] = new SqlParameter(pName, values[i]); i++; } return parameters; } /// <summary> /// 執行Sql命令 /// <example>ExecuteSqlCommandEx("delete from [Table] where ID=@0", Guid.Empty)</example> /// </summary> /// <param name="database">數據庫</param> /// <param name="sql">sql語句</param> /// <param name="values">值</param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException"></exception> /// <returns></returns> public static int ExecuteSqlCommandEx(this Database database, string sql, params object[] values) { var param = DbSetExtended.MakeSqlParameter(sql, values); return database.ExecuteSqlCommand(sql, param); } /// <summary> /// 執行Sql查詢 /// <example>SqlQueryEx("select * from [Table] where name=@0 and password=@1", "abc", "123456")</example> /// </summary> /// <param name="database">數據庫</param> /// <param name="sql">sql語句</param> /// <param name="values">值</param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException"></exception> /// <returns></returns> public static IEnumerable<TElement> SqlQueryEx<TElement>(this Database database, string sql, params object[] values) { var param = DbSetExtended.MakeSqlParameter(sql, values); return database.SqlQuery<TElement>(sql, param); } #endregion
2、排序擴展
作用:支持用字符串直接描述排序,如:OrderBy("key1,key2,key3 desc,ke4"),方便和UI交互

#region 排序擴展 /// <summary> /// 排序公共方法 /// </summary> /// <typeparam name="T">實體類型</typeparam> /// <param name="source">數據源</param> /// <param name="orderByKey">排序鍵排序鍵(不分大小寫)</param> /// <param name="orderByMethod">排序方法</param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException"></exception> /// <returns></returns> private static IOrderedQueryable<T> OrderByCommon<T>(IQueryable<T> source, string orderByKey, string orderByMethod) where T : class { if (string.IsNullOrEmpty(orderByKey)) { throw new ArgumentNullException("orderByKey"); } Type sourceTtype = typeof(T); PropertyInfo keyProperty = sourceTtype.GetProperties().FirstOrDefault(p => p.Name.ToLower().Equals(orderByKey.Trim().ToLower())); if (keyProperty == null) { throw new ArgumentException("orderByKey不存在..."); } var param = Expression.Parameter(sourceTtype, "item"); var body = Expression.MakeMemberAccess(param, keyProperty); var orderByLambda = Expression.Lambda(body, param); var resultExp = Expression.Call(typeof(Queryable), orderByMethod, new Type[] { sourceTtype, keyProperty.PropertyType }, source.Expression, Expression.Quote(orderByLambda)); var ordereQueryable = source.Provider.CreateQuery<T>(resultExp) as IOrderedQueryable<T>; return ordereQueryable; } /// <summary> /// 排序 /// 選擇升序或降序 /// </summary> /// <typeparam name="T">實體類型</typeparam> /// <param name="source">數據源</param> /// <param name="orderByKey">排序鍵排序鍵(不分大小寫)</param> /// <param name="ascending">是否升序</param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException"></exception> /// <returns></returns> public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string orderByKey, bool ascending) where T : class { var methodName = ascending ? "OrderBy" : "OrderByDescending"; return DbSetExtended.OrderByCommon(source, orderByKey, methodName); } /// <summary> /// 排序次項 /// 選擇升序或降序 /// </summary> /// <typeparam name="T">實體類型</typeparam> /// <param name="source">數據源</param> /// <param name="orderByKey">排序鍵(不分大小寫)</param> /// <param name="ascending">是否升序</param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException"></exception> /// <returns></returns> public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string orderByKey, bool ascending) where T : class { var methodName = ascending ? "ThenBy" : "ThenByDescending"; return DbSetExtended.OrderByCommon(source, orderByKey, methodName); } /// <summary> /// 多字段混合排序 /// </summary> /// <typeparam name="T">實體類型</typeparam> /// <param name="source">數據源</param> /// <param name="orderByString">排序字符串:例如CreateTime desc, ID asc 不區分大小寫</param> /// <exception cref="ArgumentNullException">orderByString</exception> /// <returns></returns> public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string orderByString) where T : class { Func<string[], bool> descFun = (item) => item.Length > 1 && item[1].Trim().ToLower().Equals("desc"); var parameters = orderByString .Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries) .Select(item => item.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)) .Select(item => new { Key = item.FirstOrDefault(), Asc = !descFun(item) }) .ToList(); if (parameters.Count == 0) { throw new ArgumentNullException("orderByString"); } var firstP = parameters.FirstOrDefault(); var orderQuery = source.OrderBy(firstP.Key, firstP.Asc); parameters.Skip(1).ToList().ForEach(p => orderQuery = orderQuery.ThenBy(p.Key, p.Asc)); return orderQuery; } /// <summary> /// 排序 /// 選擇升序或降序 /// </summary> /// <typeparam name="T">實體類型</typeparam> /// <typeparam name="TKey">排序鍵</typeparam> /// <param name="source">數據源</param> /// <param name="orderKeySelector">排序器</param> /// <param name="ascending">是否升序</param> /// <returns></returns> public static IOrderedQueryable<T> OrderBy<T, TKey>(this IQueryable<T> source, Expression<Func<T, TKey>> orderKeySelector, bool ascending) { if (ascending) { return source.OrderBy(orderKeySelector); } else { return source.OrderByDescending(orderKeySelector); } } /// <summary> /// 次項排序 /// 選擇升序或降序 /// </summary> /// <typeparam name="T">實體類型</typeparam> /// <typeparam name="TKey">排序鍵</typeparam> /// <param name="source">數據源</param> /// <param name="orderKeySelector">排序器</param> /// <param name="ascending">是否升序</param> /// <returns></returns> public static IOrderedQueryable<T> ThenBy<T, TKey>(this IOrderedQueryable<T> source, Expression<Func<T, TKey>> orderKeySelector, bool ascending) { if (ascending) { return source.ThenBy(orderKeySelector); } else { return source.ThenByDescending(orderKeySelector); } } #endregion
3、單張表省略式Select的擴展
作用:擴展后省去寫大堆的 item => new A(){A.key1 = item.key1....}

#region 查詢方法的擴展 /// <summary> /// Select方法的補充 /// rpy.SelectEx(item =>new TNew(){})等同rpy.Select(item => new TNew(){f1 = item.f1, f2 = item.f2 ,...}) /// rpy.SelectEx(item =>new TNew(){f1 = "something"})等同rpy.Select(item => new TNew(){ f1 ="something", f2 = item.f2 ,...}) /// 其它選擇方法和原始Select方法一致 /// </summary> /// <typeparam name="T">源實體類型</typeparam> /// <typeparam name="TNew">新的實體類型</typeparam> /// <param name="source">數據源</param> /// <param name="selector">新對象實例</param> /// <exception cref="ArgumentException"></exception> /// <returns></returns> public static IQueryable<TNew> SelectEx<T, TNew>(this IQueryable<T> source, Expression<Func<T, TNew>> selector) where T : class { if (selector == null) { throw new ArgumentNullException(); } var body = selector.Body as MemberInitExpression; if (body != null) { var targetType = typeof(TNew); var targetProperties = targetType.GetProperties().ToList(); var sourceProperties = typeof(T).GetProperties(); var parameter = selector.Parameters[0]; var bindedMembers = body.Bindings.Select(b => b.Member).ToList(); var needBindProroties = targetProperties.Where(p => bindedMembers.Exists(m => m.Name.Equals(p.Name)) == false); var allBindings = body.Bindings.ToList(); foreach (var property in needBindProroties) { var sourceProperty = sourceProperties.FirstOrDefault(item => item.Name.Equals(property.Name)); if (sourceProperty != null) { var memberExp = Expression.MakeMemberAccess(parameter, sourceProperty); var binding = Expression.Bind(property, memberExp); allBindings.Add(binding); } } var targetNew = Expression.New(targetType); var bodyNew = Expression.MemberInit(targetNew, allBindings); selector = (Expression<Func<T, TNew>>)Expression.Lambda(bodyNew, parameter); } return source.Select(selector); } #endregion
4、動態復雜的Where條件邏輯表達式生成的擴展
作用:生成復雜的過濾條件表達式,條件字段可以從UI上傳過來再動態生成Func<T,boo>表達式

/// <summary> /// Where條件擴展 /// 用於分步實現不確定條件個數的邏輯運算組織 /// <remarks>作者:陳國偉 日期:2013/05/07</remarks> /// </summary> public static class Where { /// <summary> /// 邏輯枚舉 /// </summary> public enum LogicEnum { /// <summary> /// 相等 /// </summary> Equal, /// <summary> /// 不等 /// </summary> NotEqual, /// <summary> /// 大於 /// </summary> GreaterThan, /// <summary> /// 大於等於 /// </summary> GreaterThanOrEqual, /// <summary> /// 小於 /// </summary> LessThan, /// <summary> /// 小於等於 /// </summary> LessThanOrEqual, /// <summary> /// 字條串的Contains /// </summary> Contains } /// <summary> /// 參數替換對象 /// </summary> private class ParameterReplacer : ExpressionVisitor { /// <summary> /// 表達式的參數 /// </summary> public ParameterExpression ParameterExpression { get; private set; } /// <summary> /// 參數替換對象 /// </summary> /// <param name="paramExp">表達式的參數</param> public ParameterReplacer(ParameterExpression paramExp) { this.ParameterExpression = paramExp; } /// <summary> /// 將表達式調度到此類中更專用的訪問方法之一 /// </summary> /// <param name="exp">表達式</param> /// <returns></returns> public Expression Replace(Expression exp) { return this.Visit(exp); } /// <summary> /// 獲取表達式的參數 /// </summary> /// <param name="p"></param> /// <returns></returns> protected override Expression VisitParameter(ParameterExpression p) { return this.ParameterExpression; } } /// <summary> /// 返回默認為True的條件 /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static Expression<Func<T, bool>> True<T>() { return item => true; } /// <summary> /// 返回默認為False的條件 /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static Expression<Func<T, bool>> False<T>() { return item => false; } /// <summary> /// 與邏輯運算 /// </summary> /// <typeparam name="T">實體類型</typeparam> /// <param name="expLeft">表達式1</param> /// <param name="expRight">表達式2</param> /// <returns></returns> public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expLeft, Expression<Func<T, bool>> expRight) { var candidateExpr = Expression.Parameter(typeof(T), "item"); var parameterReplacer = new ParameterReplacer(candidateExpr); var left = parameterReplacer.Replace(expLeft.Body); var right = parameterReplacer.Replace(expRight.Body); var body = Expression.And(left, right); return Expression.Lambda<Func<T, bool>>(body, candidateExpr); } /// <summary> /// 或邏輯運算 /// </summary> /// <typeparam name="T">實體類型</typeparam> /// <param name="expLeft">表達式1</param> /// <param name="expRight">表達式2</param> /// <returns></returns> public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expLeft, Expression<Func<T, bool>> expRight) { var candidateExpr = Expression.Parameter(typeof(T), "item"); var parameterReplacer = new ParameterReplacer(candidateExpr); var left = parameterReplacer.Replace(expLeft.Body); var right = parameterReplacer.Replace(expRight.Body); var body = Expression.Or(left, right); return Expression.Lambda<Func<T, bool>>(body, candidateExpr); } /// <summary> /// 動態生成Where邏輯表達式 /// </summary> /// <typeparam name="T">實體類型</typeparam> /// <param name="member">實體的成員(不區分大小寫)</param> /// <param name="logic">邏輯關系</param> /// <param name="matchValue">要匹配的值</param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException"></exception> /// <returns></returns> public static Expression<Func<T, bool>> Parse<T>(string member, LogicEnum logic, string matchValue) { if (string.IsNullOrEmpty(member)) { throw new ArgumentNullException("member"); } var keyProperty = typeof(T).GetProperties().FirstOrDefault(item => item.Name.ToLower().Equals(member.Trim().ToLower())); if (keyProperty == null) { throw new ArgumentException("member不存在"); } // item var pExp = Expression.Parameter(typeof(T), "item"); // item.CreateTime Expression memberExp = Expression.MakeMemberAccess(pExp, keyProperty); if (logic != LogicEnum.Contains) { // 是否是可空類型 bool memberIsNullableType = keyProperty.PropertyType.IsGenericType && keyProperty.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)); // 是可空類型則取類型的Value屬性 if (memberIsNullableType == true) { // item.CreateTime.Value memberExp = Expression.MakeMemberAccess(memberExp, keyProperty.PropertyType.GetProperty("Value")); } // 目標值類型 Type valueType = keyProperty.PropertyType; if (memberIsNullableType == true) { valueType = valueType.GetGenericArguments().FirstOrDefault(); } object value = matchValue; if (valueType.Equals(typeof(string)) == false) { // value = DateTime.Parse(matchValue) value = valueType.GetMethod("Parse", new Type[] { typeof(string) }).Invoke(null, new object[] { value }); } var valueExp = Expression.Constant(value, valueType); // Expression.Equal var expMethod = typeof(Expression).GetMethod(logic.ToString(), new Type[] { typeof(Expression), typeof(Expression) }); // item.CreateTime.Value == value var body = expMethod.Invoke(null, new object[] { memberExp, valueExp }) as Expression; return Expression.Lambda(body, pExp) as Expression<Func<T, bool>>; } else { // item.Member.Contains("something") var body = Expression.Call(memberExp, typeof(string).GetMethod(logic.ToString()), Expression.Constant(matchValue, typeof(string))); return Expression.Lambda(body, pExp) as Expression<Func<T, bool>>; } } /// <summary> /// 動態生成和匹配參數數目相同的邏輯表達式並用Or關聯起來 /// </summary> /// <typeparam name="T">實體類型</typeparam> /// <param name="member">實體成員</param> /// <param name="logic">邏輯關系</param> /// <param name="matchValues">匹配值</param> /// <returns></returns> public static Expression<Func<T, bool>> ParseOr<T>(string member, LogicEnum logic, params string[] matchValues) { var where = Where.Parse<T>(member, logic, matchValues.FirstOrDefault()); matchValues.Skip(1).ToList().ForEach(value => where = where.Or(Where.Parse<T>(member, logic, value))); return where; } /// <summary> /// 動態生成和成員目相同的邏輯表達式並用Or關聯起來 /// </summary> /// <typeparam name="T">實體類型</typeparam> /// <param name="members">實體成員</param> /// <param name="logic">邏輯關系</param> /// <param name="matchValue">匹配值</param> /// <returns></returns> public static Expression<Func<T, bool>> ParseOr<T>(string[] members, LogicEnum logic, string matchValue) { var where = Where.Parse<T>(members.FirstOrDefault(), logic, matchValue); members.Skip(1).ToList().ForEach(member => where = where.Or(Where.Parse<T>(member, logic, matchValue))); return where; } /// <summary> /// 動態生成和匹配參數數目相同的邏輯表達式並用And關聯起來 /// </summary> /// <typeparam name="T">實體類型</typeparam> /// <param name="member">實體成員</param> /// <param name="logic">邏輯關系</param> /// <param name="matchValues">匹配值</param> /// <returns></returns> public static Expression<Func<T, bool>> ParseAnd<T>(string member, LogicEnum logic, params string[] matchValues) { var where = Where.Parse<T>(member, logic, matchValues.FirstOrDefault()); matchValues.Skip(1).ToList().ForEach(value => where = where.And(Where.Parse<T>(member, logic, value))); return where; } /// <summary> /// 動態生成和成員目相同的邏輯表達式並用And關聯起來 /// </summary> /// <typeparam name="T">實體類型</typeparam> /// <param name="members">實體成員</param> /// <param name="logic">邏輯關系</param> /// <param name="matchValue">匹配值</param> /// <returns></returns> public static Expression<Func<T, bool>> ParseAnd<T>(string[] members, LogicEnum logic, string matchValue) { var where = Where.Parse<T>(members.FirstOrDefault(), logic, matchValue); members.Skip(1).ToList().ForEach(member => where = where.And(Where.Parse<T>(member, logic, matchValue))); return where; } }