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;
}
}
}