using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Transactions;
using Microsoft.EntityFrameworkCore;
using WalkingTec.Mvvm.Core.Support.Json;
namespace WalkingTec.Mvvm.Core.Extensions
{
///
/// DC相关扩展函数
///
public static class DCExtension
{
#region 树形下拉
///
/// 查询数据源,并转化成TreeSelectListItem列表
///
/// 数据源类型
/// 基础查询
/// wtm context
/// 表达式用来获取Text字段对应的值
/// 表达式用来获取Value字段对应的值,不指定则默认使用Id字段
/// 表达式用来获取icon字段对应的值
/// 表达式用来获取Url字段对应的值
/// 表达式用来获取Tag字段对应的值
/// 表达式用来获取Expanded字段对应的值,指示节点是否展开
/// 忽略数据权限判断
/// 是否根据Text字段排序,默认为是
/// SelectListItem列表
public static List GetTreeSelectListItems(this IQueryable baseQuery
, WTMContext wtmcontext
, Expression> textField
, Expression> valueField = null
, Expression> iconField = null
, Expression> urlField = null
, Expression> tagField = null
, Expression> expandField = null
, bool ignorDataPrivilege = false
, bool SortByName = true)
where T : TreePoco
{
var dps = wtmcontext?.LoginUserInfo?.DataPrivileges;
var query = baseQuery.AsNoTracking();
//如果没有指定忽略权限,则拼接权限过滤的where条件
if (ignorDataPrivilege == false)
{
query = AppendSelfDPWhere(query, wtmcontext, dps);
}
if (typeof(IPersistPoco).IsAssignableFrom(typeof(T)))
{
var mod = new IsValidModifier();
var newExp = mod.Modify(query.Expression);
query = query.Provider.CreateQuery(newExp) as IOrderedQueryable;
}
//处理后面要使用的expression
//if (valueField == null)
//{
valueField = x => x.GetID().ToString();
//}
Expression> parentField = x => x.GetParentID().ToString();
//定义PE
ParameterExpression pe = Expression.Parameter(typeof(T));
ChangePara cp = new ChangePara();
//创建新类,形成类似 new SimpleTreeTextAndValue() 的表达式
NewExpression newItem = Expression.New(typeof(TreeSelectListItem));
//绑定Text字段,形成类似 Text = textField 的表达式
var textMI = typeof(TreeSelectListItem).GetMember("Text")[0];
MemberBinding textBind = Expression.Bind(textMI, cp.Change(textField.Body, pe));
//绑定Value字段,形成类似 Value = valueField 的表达式
var valueMI = typeof(TreeSelectListItem).GetMember("Value")[0];
MemberBinding valueBind = Expression.Bind(valueMI, cp.Change(valueField.Body, pe));
//绑定ParentId字段,形成类似 Value = valueField 的表达式
var parentMI = typeof(TreeSelectListItem).GetMember("ParentId")[0];
MemberBinding parentBind = Expression.Bind(parentMI, cp.Change(parentField.Body, pe));
//绑定Url字段,形成类似 Value = valueField 的表达式
MemberBinding urlBind = null;
var urlMI = typeof(TreeSelectListItem).GetMember("Url")[0];
if (urlField != null)
{
urlBind = Expression.Bind(urlMI, cp.Change(urlField.Body, pe));
}
else
{
urlBind = Expression.Bind(urlMI, Expression.Constant(string.Empty));
}
//绑定icon字段,形成类似 Icon = iconField 的表达式
MemberBinding iconBind = null;
var iconMI = typeof(TreeSelectListItem).GetMember("Icon")[0];
if (iconField != null)
{
iconBind = Expression.Bind(iconMI, cp.Change(iconField.Body, pe));
}
else
{
iconBind = Expression.Bind(iconMI, Expression.Constant(string.Empty));
}
//绑定Tag字段,形成类似 Value = valueField 的表达式
MemberBinding tagBind = null;
var tagMI = typeof(TreeSelectListItem).GetMember("Tag")[0];
if (tagField != null)
{
tagBind = Expression.Bind(tagMI, cp.Change(tagField.Body, pe));
}
else
{
tagBind = Expression.Bind(tagMI, Expression.Constant(""));
}
//绑定Tag字段,形成类似 Value = valueField 的表达式
MemberBinding expandBind = null;
var expandMI = typeof(TreeSelectListItem).GetMember("Expended")[0];
if (expandField != null)
{
expandBind = Expression.Bind(expandMI, cp.Change(expandField.Body, pe));
}
else
{
expandBind = Expression.Bind(expandMI, Expression.Constant(false));
}
//合并创建新类和绑定字段的表达式,形成类似 new SimpleTextAndValue{ Text = textField, Value = valueField} 的表达式
MemberInitExpression init = Expression.MemberInit(newItem, textBind, valueBind, iconBind, parentBind, urlBind, tagBind, expandBind);
//将最终形成的表达式转化为Lambda,形成类似 x=> new SimpleTextAndValue { Text = x.textField, Value = x.valueField} 的表达式
var lambda = Expression.Lambda>(init, pe);
List rv = null;
//根据Text对下拉菜单数据排序
if (SortByName == true)
{
rv = query.Select(lambda).ToList().OrderBy(x => x.Text).ToList();
}
else
{
rv = query.Select(lambda).ToList();
}
List toDel = new List();
rv.ForEach(x =>
{
var c = rv.Where(y => y.ParentId == x.Value.ToString()).ToList();
x.Children = c;
toDel.AddRange(c);
});
toDel.ForEach(x => rv.Remove(x));
return rv.ToList();
}
#endregion
#region 下拉
///
/// 查询数据源,并转化成SelectListItem列表
///
/// 数据源类型
/// 基础查询
/// Wtm Context
/// SelectListItem中Text字段对应的值
/// SelectListItem中Value字段对应的值,默认为Id列
/// 忽略数据权限判断
/// 是否根据Text字段排序,默认为是
/// SelectListItem列表
public static List GetSelectListItems(this IQueryable baseQuery
, WTMContext wtmcontext
, Expression> textField
, Expression> valueField = null
, bool ignorDataPrivilege = false
, bool SortByName = true)
where T : TopBasePoco
{
var dps = wtmcontext?.LoginUserInfo?.DataPrivileges;
var query = baseQuery.AsNoTracking();
//如果value字段为空,则默认使用Id字段作为value值
if (valueField == null)
{
valueField = x => x.GetID().ToString();
}
//如果没有指定忽略权限,则拼接权限过滤的where条件
if (ignorDataPrivilege == false)
{
query = AppendSelfDPWhere(query, wtmcontext, dps);
}
if (typeof(IPersistPoco).IsAssignableFrom(typeof(T)))
{
var mod = new IsValidModifier();
var newExp = mod.Modify(query.Expression);
query = query.Provider.CreateQuery(newExp) as IOrderedQueryable;
}
//定义PE
ParameterExpression pe = Expression.Parameter(typeof(T));
ChangePara cp = new ChangePara();
//创建新类,形成类似 new SimpleTextAndValue() 的表达式
NewExpression newItem = Expression.New(typeof(ComboSelectListItem));
//绑定Text字段,形成类似 Text = textField 的表达式
var textMI = typeof(ComboSelectListItem).GetMember("Text")[0];
MemberBinding textBind = Expression.Bind(textMI, cp.Change(textField.Body, pe));
//绑定Value字段,形成类似 Value = valueField 的表达式
var valueMI = typeof(ComboSelectListItem).GetMember("Value")[0];
MemberBinding valueBind = Expression.Bind(valueMI, cp.Change(valueField.Body, pe));
//如果是树形结构,给ParentId赋值
MemberBinding parentBind = null;
var parentMI = typeof(ComboSelectListItem).GetMember("ParentId")[0];
if (typeof(TreePoco<>).IsAssignableFrom(typeof(T)))
{
var parentMember = Expression.MakeMemberAccess(pe, typeof(TreePoco<>).GetSingleProperty("ParentId"));
var p = Expression.Call(parentMember, "ToString", new Type[] { });
//var p1 = Expression.Call(p, "ToLower", new Type[] { });
parentBind = Expression.Bind(parentMI, p);
}
else
{
parentBind = Expression.Bind(parentMI, Expression.Constant(string.Empty));
}
//合并创建新类和绑定字段的表达式,形成类似 new SimpleTextAndValue{ Text = textField, Value = valueField} 的表达式
MemberInitExpression init = Expression.MemberInit(newItem, textBind, valueBind, parentBind);
//将最终形成的表达式转化为Lambda,形成类似 x=> new SimpleTextAndValue { Text = x.textField, Value = x.valueField} 的表达式
var lambda = Expression.Lambda>(init, pe);
List rv = new List();
//根据Text对下拉菜单数据排序
if (SortByName == true)
{
rv = query.Select(lambda).ToList().OrderBy(x => x.Text).ToList();
}
else
{
rv = query.Select(lambda).ToList();
}
return rv;
}
#endregion
///
/// 拼接本表的数据权限过滤
///
/// 数据类
/// 源query
/// Wtm context
/// 数据权限列表
/// 拼接好where条件的query
private static IQueryable AppendSelfDPWhere(IQueryable query, WTMContext wtmcontext, List dps) where T : TopBasePoco
{
var dpsSetting = wtmcontext?.DataPrivilegeSettings;
ParameterExpression pe = Expression.Parameter(typeof(T));
Expression peid = Expression.Property(pe, typeof(T).GetSingleProperty("ID"));
//循环数据权限,加入到where条件中,达到自动过滤的效果
if (dpsSetting?.Where(x => x.ModelName == query.ElementType.Name).SingleOrDefault() != null)
{
//如果dps参数是空,则生成 1!=1 这种错误的表达式,这样就查不到任何数据了
if (dps == null)
{
query = query.Where(Expression.Lambda>(Expression.NotEqual(Expression.Constant(1), Expression.Constant(1)), pe));
}
else
{
//在dps中找到和baseQuery源数据表名一样的关联id
var ids = dps.Where(x => x.TableName == query.ElementType.Name).Select(x => x.RelateId).ToList();
if (ids == null || ids.Count() == 0)
{
query = query.Where(Expression.Lambda>(Expression.NotEqual(Expression.Constant(1), Expression.Constant(1)), pe));
}
else
{
if (!ids.Contains(null))
{
query = query.Where(ids.GetContainIdExpression());
}
}
}
}
return query;
}
///
/// 为查询语句添加关联表的权限过滤
///
/// 源数据类
/// 源Query
///
/// 关联表外键
/// 修改后的查询语句
public static IQueryable DPWhere(this IQueryable baseQuery, WTMContext wtmcontext, params Expression>[] IdFields) where T : TopBasePoco
{
var dps = wtmcontext?.LoginUserInfo?.DataPrivileges;
//循环所有关联外键
List tableNameList = new List();
foreach (var IdField in IdFields)
{
//将外键 Id 用.分割,循环生成指向最终id的表达式,比如x=> x.a.b.Id
var fieldName = IdField.GetPropertyName(false);
//获取关联的类
string typename = "";
//如果外键名称不是‘id’,则根据model层的命名规则,它应该是xxxId,所以抹掉最后的 Id 应该是关联的类名
if (fieldName.ToLower() != "id")
{
fieldName = fieldName.Remove(fieldName.Length - 2);
typename = IdField.GetPropertyInfo().DeclaringType.GetSingleProperty(fieldName).PropertyType.Name;
}
//如果是 Id,则本身就是关联的类
else
{
typename = typeof(T).Name;
}
tableNameList.Add(typename);
}
//var test = DPWhere(baseQuery, dps, tableNameList, IdFields);
return DPWhere(baseQuery, wtmcontext, tableNameList, IdFields);
}
#region AddBy YOUKAI 20160310
///
/// 为查询语句添加关联表的权限过滤
///
/// 源数据类
/// 源Query
/// wtm context
/// 关联数据权限的表名,如果关联外键为自身,则参数第一个为自身
/// 关联表外键
/// 修改后的查询语句
public static IQueryable DPWhere(this IQueryable baseQuery, WTMContext wtmcontext, List tableName, params Expression>[] IdFields) where T : TopBasePoco
{
var dps = wtmcontext?.LoginUserInfo?.DataPrivileges;
// var dpsSetting = BaseVM.AllDPS;
ParameterExpression pe = Expression.Parameter(typeof(T));
Expression left1 = Expression.Constant(1);
Expression right1 = Expression.Constant(1);
Expression trueExp = Expression.Equal(left1, right1);
Expression falseExp = Expression.NotEqual(left1, right1);
Expression finalExp = null;
int tindex = 0;
//循环所有关联外键
foreach (var IdField in IdFields)
{
bool mtm = false;
Expression exp = trueExp;
//将外键Id用.分割,循环生成指向最终id的表达式,比如x=> x.a.b.Id
var fullname = IdField.GetPropertyName();
string[] splits = fullname.Split('.');
int leftindex = splits[0].IndexOf('[');
if (leftindex > 0)
{
mtm = true;
splits[0] = splits[0].Substring(0, leftindex);
}
Expression peid = Expression.MakeMemberAccess(pe, pe.Type.GetSingleProperty(splits[0]));
Type middletype = null;
if (mtm)
{
middletype = peid.Type.GetGenericArguments()[0];
}
else
{
for (int i = 1; i < splits.Length; i++)
{
peid = Expression.MakeMemberAccess(peid, peid.Type.GetSingleProperty(splits[i]));
}
middletype = (peid as MemberExpression).Member.DeclaringType;
}
//如果dps为空,则拼接一个返回假的表达式,这样就查询不出任何数据
if (dps == null)
{
exp = falseExp;
}
else
{
var fieldName = IdField.GetPropertyName(false);
//如果外键名称不是‘id’,则根据model层的命名规则,它应该是xxxId,所以抹掉最后的 Id 应该是关联的类名
if (fieldName.ToLower() != "id")
{
fieldName = fieldName.Remove(fieldName.Length - 2);
var typeinfo = middletype.GetSingleProperty(fieldName);
//var IsTableName = tableName?.Where(x => x == fieldName).FirstOrDefault();
var IsTableName = tableName?.Where(x => x.ToLower() == typeinfo.PropertyType.Name.ToLower()).FirstOrDefault();
if (string.IsNullOrEmpty(IsTableName))
{
continue;
}
fieldName = IsTableName;
//typename = PropertyHelper.GetPropertyInfo(IdField).DeclaringType.GetProperty(fieldName).PropertyType.Name;
}
//如果是Id,则本身就是关联的类
else
{
fieldName = tableName[tindex];
}
var dpsSetting = wtmcontext.DataPrivilegeSettings;
//循环系统设定的数据权限,如果没有和关联类一样的表,则跳过
if (dpsSetting.Where(x => x.ModelName == fieldName).SingleOrDefault() == null)
{
continue;
}
//获取dps中关联到关联类的id列表
var ids = dps.Where(x => x.TableName == fieldName).Select(x => x.RelateId).ToList();
//如果没有关联的id,则拼接一个返回假的where,是语句查询不到任何数据
if (ids == null || ids.Count() == 0)
{
exp = falseExp;
//if (peid.Type == typeof(Guid))
//{
// exp = Expression.Equal(peid, Expression.Constant(Guid.NewGuid()));
//}
//else
//{
// exp = Expression.Equal(peid, Expression.Constant(null));
//}
}
//如果有关联 Id
else
{
//如果关联 Id 不包含null,则生成类似 x=> ids.Contains(x.a.b.Id) 这种条件
//如果关联 Id 包括null,则代表可以访问所有数据,就不需要再拼接where条件了
if (!ids.Contains(null))
{
if (mtm == true)
{
ParameterExpression midpe = Expression.Parameter(middletype);
Expression middleid = Expression.PropertyOrField(midpe, IdField.GetPropertyName(false));
var queryable = Expression.Call(
typeof(Queryable),
"AsQueryable",
new Type[] { middletype },
peid);
List ddd = new List();
exp = Expression.Call(
typeof(Queryable),
"Any",
new Type[] { middletype },
queryable,
Expression.Lambda(typeof(Func<,>).MakeGenericType(middletype, typeof(bool)), ids.GetContainIdExpression(middletype, midpe, middleid).Body, new ParameterExpression[] { midpe }));
}
else
{
exp = ids.GetContainIdExpression(typeof(T), pe, peid).Body;
}
}
}
}
//把所有where里的条件用And拼接在一起
if (finalExp == null)
{
finalExp = exp;
}
else
{
finalExp = Expression.OrElse(finalExp, exp);
}
tindex++;
}
//如果没有进行任何修改,则还返回baseQuery
if (finalExp == null)
{
return baseQuery;
}
else
{
//返回加入了where条件之后的baseQuery
var query = baseQuery.Where(Expression.Lambda>(finalExp, pe));
return query;
}
}
#endregion
public static IOrderedQueryable Sort(this IQueryable baseQuery, string sortInfo, params SortInfo[] defaultSorts) where T : TopBasePoco
{
List info = new List();
IOrderedQueryable rv = null;
if (string.IsNullOrEmpty(sortInfo))
{
if (defaultSorts == null || defaultSorts.Length == 0)
{
ParameterExpression pe = Expression.Parameter(typeof(T));
var idproperty = typeof(T).GetSingleProperty("ID");
Expression pro = Expression.Property(pe, idproperty);
Type proType = typeof(Guid);
Expression final = Expression.Call(
typeof(Queryable),
"OrderBy",
new Type[] { typeof(T), proType },
baseQuery.Expression,
Expression.Lambda(pro, new ParameterExpression[] { pe }));
rv = baseQuery.Provider.CreateQuery(final) as IOrderedQueryable;
return rv;
}
else
{
info.AddRange(defaultSorts);
}
}
else
{
var temp = JsonSerializer.Deserialize>(sortInfo);
info.AddRange(temp);
}
foreach (var item in info)
{
ParameterExpression pe = Expression.Parameter(typeof(T));
var idproperty = typeof(T).GetSingleProperty(item.Property);
Expression pro = Expression.Property(pe, idproperty);
Type proType = typeof(T).GetSingleProperty(item.Property).PropertyType;
if (item.Direction == SortDir.Asc)
{
if (rv == null)
{
Expression final = Expression.Call(
typeof(Queryable),
"OrderBy",
new Type[] { typeof(T), proType },
baseQuery.Expression,
Expression.Lambda(pro, new ParameterExpression[] { pe }));
rv = baseQuery.Provider.CreateQuery(final) as IOrderedQueryable;
}
else
{
Expression final = Expression.Call(
typeof(Queryable),
"ThenBy",
new Type[] { typeof(T), proType },
rv.Expression,
Expression.Lambda(pro, new ParameterExpression[] { pe }));
rv = rv.Provider.CreateQuery(final) as IOrderedQueryable;
}
}
if (item.Direction == SortDir.Desc)
{
if (rv == null)
{
Expression final = Expression.Call(
typeof(Queryable),
"OrderByDescending",
new Type[] { typeof(T), proType },
baseQuery.Expression,
Expression.Lambda(pro, new ParameterExpression[] { pe }));
rv = baseQuery.Provider.CreateQuery(final) as IOrderedQueryable;
}
else
{
Expression final = Expression.Call(
typeof(Queryable),
"ThenByDescending",
new Type[] { typeof(T), proType },
rv.Expression,
Expression.Lambda(pro, new ParameterExpression[] { pe }));
rv = rv.Provider.CreateQuery(final) as IOrderedQueryable;
}
}
}
return rv;
}
public static IQueryable CheckID(this IQueryable baseQuery, object val, Expression> member = null)
{
ParameterExpression pe = Expression.Parameter(typeof(T));
PropertyInfo idproperty = null;
if (member == null)
{
idproperty = typeof(T).GetSingleProperty("ID");
}
else
{
idproperty = member.GetPropertyInfo();
}
Expression peid = Expression.Property(pe, idproperty);
var convertid = PropertyHelper.ConvertValue(val, idproperty.PropertyType);
return baseQuery.Where(Expression.Lambda>(Expression.Equal(peid, Expression.Constant(convertid)), pe));
}
public static IQueryable CheckParentID(this IQueryable baseQuery, string val)
{
ParameterExpression pe = Expression.Parameter(typeof(T));
PropertyInfo idproperty = null;
idproperty = typeof(T).GetSingleProperty("ParentId");
Expression peid = Expression.Property(pe, idproperty);
var p = Expression.Call(peid, "ToString", new Type[] { });
if (val == null)
{
return baseQuery.Where(Expression.Lambda>(Expression.Equal(peid, Expression.Constant(null)), pe));
}
else
{
return baseQuery.Where(Expression.Lambda>(Expression.Equal(p, Expression.Constant(val)), pe));
}
}
public static IQueryable CheckIDs(this IQueryable baseQuery, List val, Expression> member = null)
{
if (val == null)
{
return baseQuery;
}
ParameterExpression pe = Expression.Parameter(typeof(T));
PropertyInfo idproperty = null;
if (member == null)
{
idproperty = typeof(T).GetSingleProperty("ID");
}
else
{
idproperty = member.GetPropertyInfo();
}
Expression peid = Expression.Property(pe, idproperty);
var exp = val.GetContainIdExpression(typeof(T), pe, peid).Body;
return baseQuery.Where(Expression.Lambda>(exp, pe));
}
public static IQueryable CheckNotNull(this IQueryable baseQuery, Expression> member)
{
return baseQuery.CheckNotNull(member.GetPropertyName());
}
public static IQueryable CheckNotNull(this IQueryable baseQuery, string member)
{
ParameterExpression pe = Expression.Parameter(typeof(T));
PropertyInfo idproperty = typeof(T).GetSingleProperty(member);
Expression peid = Expression.Property(pe, idproperty);
return baseQuery.Where(Expression.Lambda>(Expression.NotEqual(peid, Expression.Constant(null)), pe));
}
public static IQueryable CheckNull(this IQueryable baseQuery, Expression> member)
{
ParameterExpression pe = Expression.Parameter(typeof(T));
PropertyInfo idproperty = typeof(T).GetSingleProperty(member.GetPropertyName());
Expression peid = Expression.Property(pe, idproperty);
return baseQuery.Where(Expression.Lambda>(Expression.Equal(peid, Expression.Constant(null)), pe));
}
///
/// val不为空时,附加查询条件
///
///
///
///
///
///
///
public static IQueryable CheckWhere(this IQueryable baseQuery, S val, Expression> where)
{
if (val == null)
{
return baseQuery;
}
else if (val is string s && string.IsNullOrEmpty(s))
{
return baseQuery;
}
else
{
if (typeof(IList).IsAssignableFrom(val.GetType()))
{
if (((IList)val).Count == 0)
{
return baseQuery;
}
}
return baseQuery.Where(where);
}
}
///
/// 条件为true时,附加查询条件
///
///
///
/// bool?
///
///
public static IQueryable WhereIf(this IQueryable baseQuery, bool? val, Expression> where)
{
if (val == null || val == false)
{
return baseQuery;
}
return baseQuery.Where(where);
}
public static IQueryable CheckEqual(this IQueryable baseQuery, string val, Expression> field)
{
if (val == null || val == "")
{
return baseQuery;
}
else
{
val = val.Trim();
var equal = Expression.Equal(field.Body, Expression.Constant(val));
var where = Expression.Lambda>(equal, field.Parameters[0]);
return baseQuery.Where(where);
}
}
public static IQueryable CheckEqual(this IQueryable baseQuery, S? val, Expression> field)
where S : struct
{
if (val == null)
{
return baseQuery;
}
else
{
var equal = Expression.Equal(Expression.PropertyOrField(field.Body, "Value"), Expression.Constant(val));
var where = Expression.Lambda>(equal, field.Parameters[0]);
return baseQuery.Where(where);
}
}
public static IQueryable CheckEqual(this IQueryable baseQuery, S val, Expression> field)
where S : struct
{
S? a = val;
return baseQuery.CheckEqual(a, field);
}
public static IQueryable CheckBetween(this IQueryable baseQuery, S? valMin, S? valMax, Expression> field, bool includeMin = true, bool includeMax = true)
where S : struct
{
if (valMin == null && valMax == null)
{
return baseQuery;
}
else
{
IQueryable rv = baseQuery;
if (valMin != null)
{
BinaryExpression exp1 = !includeMin ? Expression.GreaterThan(Expression.PropertyOrField(field.Body, "Value"), Expression.Constant(valMin)) : Expression.GreaterThanOrEqual(Expression.PropertyOrField(field.Body, "Value"), Expression.Constant(valMin));
rv = rv.Where(Expression.Lambda>(exp1, field.Parameters[0]));
}
if (valMax != null)
{
BinaryExpression exp2 = !includeMax ? Expression.LessThan(Expression.PropertyOrField(field.Body, "Value"), Expression.Constant(valMax)) : Expression.LessThanOrEqual(Expression.PropertyOrField(field.Body, "Value"), Expression.Constant(valMax));
rv = rv.Where(Expression.Lambda>(exp2, field.Parameters[0]));
}
return rv;
}
}
public static IQueryable CheckBetween(this IQueryable baseQuery, S valMin, S valMax, Expression> field, bool includeMin = true, bool includeMax = true)
where S : struct
{
S? a = valMin;
S? b = valMax;
return CheckBetween(baseQuery, a, b, field, includeMin, includeMax);
}
public static IQueryable CheckBetween(this IQueryable baseQuery, S? valMin, S valMax, Expression> field, bool includeMin = true, bool includeMax = true)
where S : struct
{
S? a = valMin;
S? b = valMax;
return CheckBetween(baseQuery, a, b, field, includeMin, includeMax);
}
public static IQueryable CheckBetween(this IQueryable baseQuery, S valMin, S? valMax, Expression> field, bool includeMin = true, bool includeMax = true)
where S : struct
{
S? a = valMin;
S? b = valMax;
return CheckBetween(baseQuery, a, b, field, includeMin, includeMax);
}
public static IQueryable CheckContain(this IQueryable baseQuery, string val, Expression> field, bool ignoreCase = true)
{
if (string.IsNullOrEmpty(val))
{
return baseQuery;
}
else
{
val = val.Trim();
Expression exp = null;
if (ignoreCase == true)
{
var tolower = Expression.Call(field.Body, "ToLower", null);
exp = Expression.Call(tolower, "Contains", null, Expression.Constant(val.ToLower()));
}
else
{
exp = Expression.Call(field.Body, "Contains", null, Expression.Constant(val));
}
var where = Expression.Lambda>(exp, field.Parameters[0]);
return baseQuery.Where(where);
}
}
public static IQueryable CheckContain(this IQueryable baseQuery, List val, Expression> field)
{
if (val == null || val.Count == 0 || (val.Count == 1 && val[0] == null))
{
return baseQuery;
}
else
{
Expression exp = null;
exp = Expression.Call(Expression.Constant(val), "Contains", null, field.Body);
var where = Expression.Lambda>(exp, field.Parameters[0]);
return baseQuery.Where(where);
}
}
public static IQueryable DynamicSelect(this IQueryable baseQuery, string fieldName)
{
ParameterExpression pe = Expression.Parameter(typeof(T));
var idproperty = typeof(T).GetSingleProperty(fieldName);
Expression pro = Expression.Property(pe, idproperty);
Expression tostring = Expression.Call(pro, "ToString", new Type[] { });
Type proType = typeof(string);
Expression final = Expression.Call(
typeof(Queryable),
"Select",
new Type[] { typeof(T), proType },
baseQuery.Expression,
Expression.Lambda(tostring, new ParameterExpression[] { pe }));
var rv = baseQuery.Provider.CreateQuery(final) as IOrderedQueryable;
return rv;
}
public static string GetTableName(this IDataContext self)
{
return self.Model.FindEntityType(typeof(T)).GetTableName();
}
///
/// 通过模型和模型的某个List属性的名称来判断List的字表中关联到主表的主键名称
///
/// 主表Model
/// DataContext
/// 主表中的子表List属性名称
/// 主键名称
public static string GetFKName(this IDataContext self, string listFieldName) where T : class
{
return GetFKName(self, typeof(T), listFieldName);
}
///
/// 通过模型和模型的某个List属性的名称来判断List的字表中关联到主表的主键名称
///
/// DataContext
/// 主表model类型
/// 主表中的子表List属性名称
/// 主键名称
public static string GetFKName(this IDataContext self, Type sourceType, string listFieldName)
{
try
{
var test = self.Model.FindEntityType(sourceType).GetReferencingForeignKeys().Where(x => x.PrincipalToDependent?.Name == listFieldName).FirstOrDefault();
if (test != null && test.Properties.Count > 0)
{
return test.Properties[0].Name;
}
else
{
return "";
}
}
catch
{
return "";
}
}
///
/// 通过子表模型和模型关联到主表的属性名称来判断该属性对应的主键名称
///
/// 子表Model
/// DataContext
/// 关联主表的属性名称
/// 主键名称
public static string GetFKName2(this IDataContext self, string FieldName) where T : class
{
return GetFKName2(self, typeof(T), FieldName);
}
///
/// 通过模型和模型关联到主表的属性名称来判断该属性对应的主键名称
///
/// DataContext
/// 子表model类型
/// 关联主表的属性名称
/// 主键名称
public static string GetFKName2(this IDataContext self, Type sourceType, string FieldName)
{
try
{
var test = self.Model.FindEntityType(sourceType).GetForeignKeys().Where(x => x.DependentToPrincipal?.Name == FieldName).FirstOrDefault();
if (test != null && test.Properties.Count > 0)
{
return test.Properties[0].Name;
}
else
{
return "";
}
}
catch
{
return "";
}
}
public static string GetFieldName(this IDataContext self, Expression> field)
{
string pname = field.GetPropertyName();
return self.GetFieldName(pname);
}
public static string GetFieldName(this IDataContext self, string fieldname)
{
var rv = self.Model.FindEntityType(typeof(T)).FindProperty(fieldname);
return rv?.GetColumnName(new Microsoft.EntityFrameworkCore.Metadata.StoreObjectIdentifier());
}
public static string GetPropertyNameByFk(this IDataContext self, Type sourceType, string fkname)
{
try
{
var test = self.Model.FindEntityType(sourceType).GetForeignKeys().Where(x => x.DependentToPrincipal?.ForeignKey?.Properties[0]?.Name == fkname).FirstOrDefault();
if (test != null && test.Properties.Count > 0)
{
return test.DependentToPrincipal.Name;
}
else
{
return "";
}
}
catch
{
return "";
}
}
public static Expression> GetContainIdExpression(this List Ids, Expression peid = null)
{
ParameterExpression pe = Expression.Parameter(typeof(TModel));
var rv = Ids.GetContainIdExpression(typeof(TModel), pe, peid) as Expression>;
return rv;
}
public static LambdaExpression GetContainIdExpression(this List Ids, Type modeltype, ParameterExpression pe, Expression peid = null)
{
if (Ids == null)
{
Ids = new List();
}
if (peid == null)
{
peid = Expression.Property(pe, modeltype.GetSingleProperty("ID"));
}
else
{
ChangePara cp = new ChangePara();
peid = cp.Change(peid, pe);
}
List