AsNoTracking 不能查詢多級導航(導航的導航)實體問題,另附加 Expression Helper
阿新 • • 發佈:2022-05-18
當設定.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);
}
}
}