1. 程式人生 > 其它 >AsNoTracking 不能查詢多級導航(導航的導航)實體問題,另附加 Expression Helper

AsNoTracking 不能查詢多級導航(導航的導航)實體問題,另附加 Expression Helper

當設定.AsNoTracking()時,後續實體不會再更新,所以如果實體類中的導航實體中還包含實體,則無法附加到其中。

另外附加Expression Helper幫助類

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Linq;
using System.Text;
using TemplateNetCore.Framwork.Extensions;

namespace TemplateNetCore.Framwork.
Helpers
{ public static class LambdaHelper { /// <summary> /// 建立lambda表示式:p=>true /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static Expression<Func<T, bool>> True
<T>
() { return p => true; } /// <summary> /// 建立lambda表示式:p=>false /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static Expression<Func<T, bool
>>
False<T>() { return p => false; } /// <summary> /// 建立lambda表示式:p=>p.propertyName /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TKey"></typeparam> /// <param name="sort"></param> /// <returns></returns> public static Expression<Func<T, TKey>> OrderExpression<T, TKey>(string propertyName) { ParameterExpression parameter = Expression.Parameter(typeof(T), "p"); return Expression.Lambda<Func<T, TKey>>(Expression.Property(parameter, propertyName), parameter); } #region build selecter /// <summary> /// 建立lambda selecter:p=>{p.propertyName,p.propertyName1} /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TKey"></typeparam> /// <param name="Fields">欄位,‘,’隔開</param> /// <returns></returns> public static Expression<Func<TSource, T>> SelecterExpression<TSource, T>(string Fields) where TSource : class { ParameterExpression parameter = Expression.Parameter(typeof(TSource), "p"); var tType = typeof(TSource); var props = tType.GetProperties(); var dType = typeof(T); var dMembers = dType.GetMembers(); List<MemberBinding> bindings = new List<MemberBinding>(); foreach (string field in Fields.Split(',', StringSplitOptions.RemoveEmptyEntries)) { if (props.Where(s => s.Name.ToUpper() == field.ToUpper()).Count() > 0) { MemberExpression memberExpression = Expression.PropertyOrField(parameter, field); bindings.Add(Expression.Bind(Array.Find(dMembers, m => m.Name.ToUpper() == field.ToUpper()), memberExpression)); } } Expression body = Expression.MemberInit(Expression.New(dType), bindings); Expression<Func<TSource, T>> selector = (Expression<Func<TSource, T>>)Expression.Lambda(body, parameter); return selector; } /// <summary> /// 建立lambda selecter:p=>{p.propertyName,p.propertyName1} ,如果須要查詢子項如 x = a.b 或者 x = a.b.c /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TTarget"></typeparam> /// <param name="members"></param> /// <returns></returns> public static Expression<Func<TSource, TTarget>> BuildSelector<TSource, TTarget>(string members) => BuildSelector<TSource, TTarget>(members.Split(',').Select(m => m.Trim())); public static Expression<Func<TSource, TTarget>> BuildSelector<TSource, TTarget>(IEnumerable<string> members) { var parameter = Expression.Parameter(typeof(TSource), "e"); var body = NewObject(typeof(TTarget), parameter, members.Select(m => m.Split('.'))); return Expression.Lambda<Func<TSource, TTarget>>(body, parameter); } static Expression NewObject(Type targetType, Expression source, IEnumerable<string[]> memberPaths, int depth = 0) { var bindings = new List<MemberBinding>(); var target = Expression.Constant(null, targetType); foreach (var memberGroup in memberPaths.GroupBy(path => path[depth])) { var memberName = memberGroup.Key; var targetMember = Expression.PropertyOrField(target, memberName); var sourceMember = Expression.PropertyOrField(source, memberName); var childMembers = memberGroup.Where(path => depth + 1 < path.Length); var targetValue = !childMembers.Any() ? sourceMember : NewObject(targetMember.Type, sourceMember, childMembers, depth + 1); bindings.Add(Expression.Bind(targetMember.Member, targetValue)); } return Expression.MemberInit(Expression.New(targetType), bindings); } #endregion /// <summary> /// 建立lambda表示式:p=>p.propertyName == propertyValue /// </summary> /// <typeparam name="T"></typeparam> /// <param name="column"></param> /// <param name="value"></param> /// <returns></returns> public static Expression<Func<T, bool>> EqualExpression<T>(string propertyName, object propertyValue) { Type tProp = typeof(T).GetProperty(propertyName).PropertyType; ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//建立引數p MemberExpression member = Expression.PropertyOrField(parameter, propertyName); ConstantExpression constant = null; if (tProp.FullName.Contains("Int")) { propertyValue = (int)propertyValue; if (tProp.FullName.Contains("Nullable")) { constant = Expression.Constant(propertyValue, typeof(int?)); } } else if (tProp.FullName.Contains("String")) { propertyValue = propertyValue.ToString(); constant = Expression.Constant(propertyValue); } else if (tProp.FullName.Contains("DateTime")) { propertyValue = DateTime.Parse(propertyValue.ToString()); if (tProp.FullName.Contains("Nullable")) { constant = Expression.Constant(propertyValue, typeof(DateTime?)); } } else { constant = Expression.Constant(propertyValue); } if (!tProp.FullName.Contains("Nullable")) { constant = Expression.Constant(propertyValue); } return Expression.Lambda<Func<T, bool>>(Expression.Equal(member, constant), parameter); } /// <summary> /// 建立lambda表示式:p=>p.propertyName != propertyValue /// </summary> /// <typeparam name="T"></typeparam> /// <param name="propertyName"></param> /// <param name="propertyValue"></param> /// <returns></returns> public static Expression<Func<T, bool>> NotEqualExpression<T>(string propertyName, object propertyValue) { ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//建立引數p MemberExpression member = Expression.PropertyOrField(parameter, propertyName); ConstantExpression constant = Expression.Constant(propertyValue);//建立常數 return Expression.Lambda<Func<T, bool>>(Expression.NotEqual(member, constant), parameter); } /// <summary> /// 建立lambda表示式:p=>p.propertyName > propertyValue /// </summary> /// <typeparam name="T"></typeparam> /// <param name="column"></param> /// <param name="value"></param> /// <returns></returns> public static Expression<Func<T, bool>> GreaterThanExpression<T>(string propertyName, object propertyValue) { ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//建立引數p MemberExpression member = Expression.PropertyOrField(parameter, propertyName); ConstantExpression constant = Expression.Constant(propertyValue);//建立常數 return Expression.Lambda<Func<T, bool>>(Expression.GreaterThan(member, constant), parameter); } /// <summary> /// 建立lambda表示式:p=>p.propertyName < propertyValue /// </summary> /// <typeparam name="T"></typeparam> /// <param name="column"></param> /// <param name="value"></param> /// <returns></returns> public static Expression<Func<T, bool>> LessThanExpression<T>(string propertyName, object propertyValue) { ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//建立引數p MemberExpression member = Expression.PropertyOrField(parameter, propertyName); ConstantExpression constant = Expression.Constant(propertyValue);//建立常數 return Expression.Lambda<Func<T, bool>>(Expression.LessThan(member, constant), parameter); } /// <summary> /// 建立lambda表示式:p=>p.propertyName >= propertyValue /// </summary> /// <typeparam name="T"></typeparam> /// <param name="column"></param> /// <param name="value"></param> /// <returns></returns> public static Expression<Func<T, bool>> GreaterThanOrEqualExpression<T>(string propertyName, object propertyValue) { Type tProp = typeof(T).GetProperty(propertyName).PropertyType; ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//建立引數p MemberExpression member = Expression.PropertyOrField(parameter, propertyName); ConstantExpression constant = null; if (tProp.FullName.Contains("Int")) { propertyValue = (int)propertyValue; if (tProp.FullName.Contains("Nullable")) { constant = Expression.Constant(propertyValue, typeof(int?)); } } else if (tProp.FullName.Contains("String")) { propertyValue = propertyValue.ToString(); constant = Expression.Constant(propertyValue); } else if (tProp.FullName.Contains("DateTime")) { propertyValue = DateTime.Parse(propertyValue.ToString()); if (tProp.FullName.Contains("Nullable")) { constant = Expression.Constant(propertyValue, typeof(DateTime?)); } } else { constant = Expression.Constant(propertyValue); } if (!tProp.FullName.Contains("Nullable")) { constant = Expression.Constant(propertyValue); } return Expression.Lambda<Func<T, bool>>(Expression.GreaterThanOrEqual(member, constant), parameter); } /// <summary> /// 建立lambda表示式:p=>p.propertyName <= propertyValue /// </summary> /// <typeparam name="T"></typeparam> /// <param name="column"></param> /// <param name="value"></param> /// <returns></returns> public static Expression<Func<T, bool>> LessThanOrEqualExpression<T>(string propertyName, object propertyValue) { ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//建立引數p MemberExpression member = Expression.PropertyOrField(parameter, propertyName); ConstantExpression constant = Expression.Constant(propertyValue);//建立常數 return Expression.Lambda<Func<T, bool>>(Expression.LessThanOrEqual(member, constant), parameter); } /// <summary> /// 建立lambda表示式:p=>p.propertyName.Contains(propertyValue) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="column"></param> /// <param name="value"></param> /// <returns></returns> public static Expression<Func<T, bool>> ContainsExpression<T>(string propertyName, object propertyValue) { ParameterExpression parameter = Expression.Parameter(typeof(T), "p"); MemberExpression member = Expression.PropertyOrField(parameter, propertyName); MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); ConstantExpression constant = Expression.Constant(propertyValue, typeof(string)); return Expression.Lambda<Func<T, bool>>(Expression.Call(member, method, constant), parameter); } /// <summary> /// 建立lambda表示式:!(p=>p.propertyName.Contains(propertyValue)) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="column"></param> /// <param name="value"></param> /// <returns></returns> public static Expression<Func<T, bool>> NotContainsExpression<T>(string propertyName, object propertyValue) { ParameterExpression parameter = Expression.Parameter(typeof(T), "p"); MemberExpression member = Expression.PropertyOrField(parameter, propertyName); MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); ConstantExpression constant = Expression.Constant(propertyValue, typeof(string)); return Expression.Lambda<Func<T, bool>>(Expression.Not(Expression.Call(member, method, constant)), parameter); } } public static class DataTypeHelper1 { public static object ChanageType(this object value, Type convertsionType) { //判斷convertsionType型別是否為泛型,因為nullable是泛型類, if (convertsionType.IsGenericType && //判斷convertsionType是否為nullable泛型類 convertsionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) { if (value == null || value.ToString().Length == 0) { return null; } //如果convertsionType為nullable類,宣告一個NullableConverter類,該類提供從Nullable類到基礎基元型別的轉換 System.ComponentModel.NullableConverter nullableConverter = new System.ComponentModel.NullableConverter(convertsionType); //將convertsionType轉換為nullable對的基礎基元型別 convertsionType = nullableConverter.NullableType; } return Convert.ChangeType(value, convertsionType); } } }