using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.Entity; using System.Linq.Dynamic; using System.Linq.Expressions; using System.Data.Entity.Infrastructure; //using System.Data.Objects; using System.Reflection; using System.Data; using System.Collections; using System.Data.Entity.Core.Objects; using System.Web; namespace Bowin.Common.Linq.Entity { /// /// Helper extensions for add IDbSet methods defined only /// for DbSet and ObjectQuery /// public static class IQueryableExtensions { /// /// 映射。 /// /// /// /// public static ExpressionFactory Map(this IQueryable queryable) { return new ExpressionFactory(queryable); } /// /// Include extension method for IDbSet /// /// var query = ReturnTheQuery(); /// query = query.Include(customer=>customer.Orders);//"Orders" /// //or /// query = query.Include(customer=>customer.Orders.Select(o=>o.OrderDetails) //"Orders.OrderDetails" /// /// /// Type of elements in IQueryable /// Type of navigated element /// Queryable object /// Expression with path to include /// Queryable object with include path information public static IQueryable Include(this IDbSet queryable, Expression> path) where TEntity : class { var objectQuery = queryable as DbQuery; if (objectQuery != null) //Is DBSET { return objectQuery.Include(path); } else // probably mock return queryable; } /// /// OfType extension method for IQueryable /// /// The type to filter the elements of the sequence on. /// The queryable object /// /// A new IQueryable hat contains elements from /// the input sequence of type TResult /// public static IQueryable OfType(this IQueryable queryable) where TEntity : class where KEntity : class,TEntity { var objectQuery = queryable as DbQuery; if (objectQuery != null) //is DBSET { return objectQuery.OfType(); } else // probably IDbSet Mock return queryable.OfType(); } public static IGridResultSet ToGridResultSet(this IQueryable dataSource, int? pageIndex = null, int? pageSize = null) { var orderby = (OrderByStatementView)HttpContext.Current.Session["Bowin_Common_Linq_Entity_CurOrderby"]; if (orderby != null) { if (orderby.isAsc) { dataSource = dataSource.OrderBy(orderby.OrderBy); } else { dataSource = dataSource.OrderBy(orderby.OrderBy + " desc"); } HttpContext.Current.Session["Bowin_Common_Linq_Entity_CurOrderby"] = null; } if (pageIndex.HasValue && pageSize.HasValue) { return new GridResultSet { rows = dataSource.Skip(pageIndex.Value * pageSize.Value).Take(pageSize.Value).ToList(), total = dataSource.Count() }; } else { var result = new GridResultSet { rows = dataSource.ToList() }; result.total = result.rows.Count; return result; } } public static IQueryable DynamicWhere(this IQueryable dataSource, string propertyName, string comparer, object value) { ExpressionFactory factory = new ExpressionFactory(dataSource); return dataSource.Where(factory.DynamicExpression(propertyName, comparer, value)); } public static IQueryable DynamicInWhere(this IQueryable dataSource, string propertyName, IList value) { ExpressionFactory factory = new ExpressionFactory(dataSource); return dataSource.Where(factory.DynamicInExpression(propertyName, value)); } /// /// 分页查询,当 pageIndex 或 pageSize 为null时,获取全部数据。 /// /// 实体类型 /// 分页数据源 /// 页码,从1开始 /// 页数 /// public static PageList ToPageList(this IQueryable query, int? pageIndex, int? pageSize) { return new PageList(query, pageIndex, pageSize); } public static ObjectParameterCollection GetParamters(this IQueryable linqBody) { var internalQueryField = linqBody.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(f => f.Name.Equals("_internalSet")).FirstOrDefault(); if (internalQueryField == null) { internalQueryField = linqBody.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(f => f.Name.Equals("_internalQuery")).FirstOrDefault(); } var internalQuery = internalQueryField.GetValue(linqBody); var objectQueryField = internalQuery.GetType().GetProperties().Where(f => f.Name.Equals("ObjectQuery")).FirstOrDefault(); var objectQuery = objectQueryField.GetValue(internalQuery, null) as ObjectQuery; var paras = objectQuery.Parameters; return paras; } public static IDbConnection GetConnection(this IQueryable queryable) { var internalQueryField = queryable.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(f => f.Name.Equals("_internalSet")).FirstOrDefault(); if (internalQueryField == null) { internalQueryField = queryable.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(f => f.Name.Equals("_internalQuery")).FirstOrDefault(); } var internalQuery = internalQueryField.GetValue(queryable); var internalContextField = internalQuery.GetType().GetProperties().Where(f => f.Name.Equals("InternalContext")).FirstOrDefault(); var internalContext = internalContextField.GetValue(internalQuery, null); var internalConnectionField = internalContext.GetType().GetProperties().Where(p => p.Name.Equals("Connection")).FirstOrDefault(); var internalConnection = internalConnectionField.GetValue(internalContext, null); //var underlyingConnectionProperty = internalConnection.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance).Where(p => p.Name.Equals("UnderlyingConnection")).FirstOrDefault(); //var underlyingConnection = underlyingConnectionProperty.GetValue(internalConnection, null); return (IDbConnection)internalConnection; } public static string GetConnectionKey(this IQueryable queryable) { var internalQueryField = queryable.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(f => f.Name.Equals("_internalSet")).FirstOrDefault(); if (internalQueryField == null) { internalQueryField = queryable.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(f => f.Name.Equals("_internalQuery")).FirstOrDefault(); } var internalQuery = internalQueryField.GetValue(queryable); var internalContextField = internalQuery.GetType().GetProperties().Where(f => f.Name.Equals("InternalContext")).FirstOrDefault(); var internalContext = internalContextField.GetValue(internalQuery, null); var objectContextProp = internalContext.GetType().GetProperty("ConnectionStringName", BindingFlags.Public | BindingFlags.Instance); string contextName = objectContextProp.GetValue(internalContext, null).ToString(); return contextName; } public static string GetDbConnectionKey(this DbContext db) { var internalContextField = typeof(System.Data.Entity.DbContext).GetField("_internalContext", BindingFlags.NonPublic | BindingFlags.Instance); var internalContext = internalContextField.GetValue(db); var objectContextProp = internalContext.GetType().GetProperty("ConnectionStringName", BindingFlags.Public | BindingFlags.Instance); string contextName = objectContextProp.GetValue(internalContext, null).ToString(); return contextName; } public static IQueryable OrderBy(this IQueryable source, string propertyName, bool ascending) where T : class { Type type = typeof(T); PropertyInfo property = type.GetProperty(propertyName); if (property == null) throw new ArgumentException("propertyName", "Not Exist"); ParameterExpression param = Expression.Parameter(type, "p"); Expression propertyAccessExpression = Expression.MakeMemberAccess(param, property); LambdaExpression orderByExpression = Expression.Lambda(propertyAccessExpression, param); string methodName = ascending ? "OrderBy" : "OrderByDescending"; MethodCallExpression exp = Expression.Call( typeof(Queryable) , methodName , new Type[] { type, property.PropertyType } , source.Expression , Expression.Quote(orderByExpression)); return source.Provider.CreateQuery(exp); } /// /// 将集合类转换成DataTable /// /// 集合 /// public static DataTable ToDataTable(this List list) { DataTable result = new DataTable(); if (list.Count > 0) { PropertyInfo[] propertys = list[0].GetType().GetProperties(); foreach (PropertyInfo pi in propertys) { result.Columns.Add(pi.Name, pi.PropertyType); } for (int i = 0; i < list.Count; i++) { ArrayList tempList = new ArrayList(); foreach (PropertyInfo pi in propertys) { object obj = pi.GetValue(list[i], null); tempList.Add(obj); } object[] array = tempList.ToArray(); result.LoadDataRow(array, true); } } return result; } } }