Support NavigateType.Dynamic

This commit is contained in:
sunkaixuan
2022-04-29 18:50:48 +08:00
parent 29f07ecae7
commit 0ba1390794
8 changed files with 250 additions and 5 deletions

View File

@@ -0,0 +1,176 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace SqlSugar
{
internal class MappingFieldsHelper<T>
{
public SqlSugarProvider Context { get; set; }
public EntityInfo NavEntity { get; set; }
public EntityInfo RootEntity { get; set; }
public MappingFieldsInfo GetMappings(Expression thisFiled, Expression mappingFiled)
{
MappingFieldsInfo mappingFields=new MappingFieldsInfo();
var pkName = "";
if ((mappingFiled as LambdaExpression).Body is UnaryExpression)
{
pkName = (((mappingFiled as LambdaExpression).Body as UnaryExpression).Operand as MemberExpression).Member.Name;
}
else
{
pkName = ((mappingFiled as LambdaExpression).Body as MemberExpression).Member.Name;
}
return mappingFields;
}
public List<IConditionalModel> GetMppingSql(List<T> list, List<MappingFieldsExpression> mappingFieldsExpressions)
{
List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
foreach (var model in list)
{
var clist = new List<KeyValuePair<WhereType, ConditionalModel>>();
foreach (var item in mappingFieldsExpressions)
{
InitMappingFieldsExpression(item);
clist.Add(new KeyValuePair<WhereType, ConditionalModel>(WhereType.Or, new ConditionalModel()
{
FieldName = item.LeftEntityColumn.DbColumnName,
ConditionalType = ConditionalType.Equal,
FieldValue = item.RightEntityColumn.PropertyInfo.GetValue(model).ObjToString(),
CSharpTypeName = item.RightEntityColumn.PropertyInfo.PropertyType.Name
}));
}
conditionalModels.Add(new ConditionalCollections() {
ConditionalList= clist
});
}
return conditionalModels;
}
public void SetChildList(EntityColumnInfo navColumnInfo,object item,List<object> list, List<MappingFieldsExpression> mappingFieldsExpressions)
{
if (item != null)
{
//var expable =Expressionable.Create<object>();
foreach (var field in mappingFieldsExpressions)
{
InitMappingFieldsExpression(field);
}
var setList =new List<object>();
var count = mappingFieldsExpressions.Count;
if (count == 1)
{
setList=list.Where(it => GetWhereByIndex(item, mappingFieldsExpressions, it, 0)).ToList();
}
else if (count == 2)
{
setList = list.Where(it =>
GetWhereByIndex(item, mappingFieldsExpressions, it, 0) ||
GetWhereByIndex(item, mappingFieldsExpressions, it, 1)
).ToList();
}
else if (count == 3)
{
setList = list.Where(it =>
GetWhereByIndex(item, mappingFieldsExpressions, it, 0) ||
GetWhereByIndex(item, mappingFieldsExpressions, it, 1) ||
GetWhereByIndex(item, mappingFieldsExpressions, it, 2)
).ToList();
}
else if (count == 4)
{
setList = list.Where(it =>
GetWhereByIndex(item, mappingFieldsExpressions, it, 0) ||
GetWhereByIndex(item, mappingFieldsExpressions, it, 1) ||
GetWhereByIndex(item, mappingFieldsExpressions, it, 2) ||
GetWhereByIndex(item, mappingFieldsExpressions, it, 3)
).ToList();
}
else if (count == 5)
{
setList = list.Where(it =>
GetWhereByIndex(item, mappingFieldsExpressions, it, 0) ||
GetWhereByIndex(item, mappingFieldsExpressions, it, 1) ||
GetWhereByIndex(item, mappingFieldsExpressions, it, 2) ||
GetWhereByIndex(item, mappingFieldsExpressions, it, 3) ||
GetWhereByIndex(item, mappingFieldsExpressions, it, 4)
).ToList();
}
else
{
Check.ExceptionEasy("MappingField max value is 5", "MappingField最大数量不能超过5");
}
//navColumnInfo.PropertyInfo.SetValue();
var instance = Activator.CreateInstance(navColumnInfo.PropertyInfo.PropertyType, true);
var ilist = instance as IList;
foreach (var value in setList)
{
ilist.Add(value);
}
navColumnInfo.PropertyInfo.SetValue(item,ilist);
}
}
private static bool GetWhereByIndex(object item, List<MappingFieldsExpression> mappingFieldsExpressions, object it,int index)
{
return mappingFieldsExpressions[index].LeftEntityColumn.PropertyInfo.GetValue(it).ObjToString() == mappingFieldsExpressions[index].RightEntityColumn.PropertyInfo.GetValue(item).ObjToString();
}
private void InitMappingFieldsExpression(MappingFieldsExpression item)
{
var leftName = item.LeftName;
var rightName = item.RightName;
if (item.LeftEntityColumn == null)
{
item.LeftEntityColumn = this.NavEntity.Columns.FirstOrDefault(it => it.PropertyName == leftName);
}
if (item.RightEntityColumn == null)
{
item.RightEntityColumn = this.RootEntity.Columns.FirstOrDefault(it => it.PropertyName == rightName);
}
}
}
public class MappingFieldsInfo
{
public DbColumnInfo LeftColumn { get; set; }
public DbColumnInfo RightColumn { get; set; }
}
public class MappingFieldsExpression
{
public Expression LeftColumnExpression { get; set; }
public Expression RightColumnExpression { get; set; }
public EntityColumnInfo LeftEntityColumn { get; set; }
public EntityColumnInfo RightEntityColumn { get; set; }
private string _LeftName;
public string LeftName
{
get
{
if (_LeftName == null)
{
_LeftName = ExpressionTool.GetMemberName(this.LeftColumnExpression);
}
return _LeftName;
}
}
private string _RightName;
public string RightName
{
get
{
if (_RightName == null)
{
_RightName = ExpressionTool.GetMemberName(this.RightColumnExpression);
}
return _RightName;
}
}
}
}

View File

@@ -165,6 +165,10 @@ namespace SqlSugar
{
OneToOne(list, selector, listItemEntity, navObjectNamePropety, navObjectNameColumnInfo);
}
else if (navObjectNameColumnInfo.Navigat.NavigatType == NavigateType.Dynamic)
{
Dynamic(list, selector, listItemEntity, navObjectNamePropety, navObjectNameColumnInfo);
}
else
{
ManyToMany(list, selector, listItemEntity, navObjectNamePropety, navObjectNameColumnInfo);
@@ -312,6 +316,30 @@ namespace SqlSugar
}
}
private void Dynamic(List<object> list, Func<ISugarQueryable<object>, List<object>> selector, EntityInfo listItemEntity, System.Reflection.PropertyInfo navObjectNamePropety, EntityColumnInfo navObjectNameColumnInfo)
{
var navEntity = navObjectNameColumnInfo.PropertyInfo.PropertyType.GetGenericArguments()[0];
var navEntityInfo = this.Context.EntityMaintenance.GetEntityInfo(navEntity);
var sqlObj = GetWhereSql(navObjectNameColumnInfo.Navigat.Name);
Check.ExceptionEasy(sqlObj.MappingExpressions.IsNullOrEmpty(), $"Dynamic need MappingField ,Demo: Includes(it => it.Books.MappingField(z=>z.studenId,()=>it.StudentId).ToList())", $"自定义映射需要 MappingFields ,例子: Includes(it => it.Books.MappingFields(z=>z.studenId,()=>it.StudentId).ToList())");
if (list.Any() && navObjectNamePropety.GetValue(list.First()) == null)
{
MappingFieldsHelper<T> helper = new MappingFieldsHelper<T>();
helper.Context = this.Context;
helper.NavEntity = navEntityInfo;
helper.RootEntity = this.Context.EntityMaintenance.GetEntityInfo<T>();
var whereSql = helper.GetMppingSql(RootList,sqlObj.MappingExpressions);
var navList = selector(this.Context.Queryable<object>().AS(navEntityInfo.DbTableName).AddParameters(sqlObj.Parameters).Where(whereSql,true).WhereIF(sqlObj.WhereString.HasValue(), sqlObj.WhereString).Select(sqlObj.SelectString).OrderByIF(sqlObj.OrderByString.HasValue(), sqlObj.OrderByString));
if (navList.HasValue())
{
foreach (var item in list)
{
helper.SetChildList(navObjectNameColumnInfo, item, navList, sqlObj.MappingExpressions);
}
}
}
}
private SqlInfo GetWhereSql(string properyName=null)
{
if (_ListCallFunc == null|| _ListCallFunc.Count==0) return new SqlInfo();
@@ -344,6 +372,16 @@ namespace SqlSugar
var exp = method.Arguments[1];
oredrBy.Add(" " + queryable.QueryBuilder.GetExpressionValue(exp, ResolveExpressType.WhereSingle).GetString());
}
else if (method.Method.Name == "MappingField")
{
if (result.MappingExpressions == null)
result.MappingExpressions = new List<MappingFieldsExpression>();
result.MappingExpressions.Add(new MappingFieldsExpression()
{
LeftColumnExpression = method.Arguments[1],
RightColumnExpression = method.Arguments[2]
});
}
else if (method.Method.Name == "Select")
{
var exp = method.Arguments[1];
@@ -436,6 +474,7 @@ namespace SqlSugar
public string OrderByString { get; set; }
public string SelectString { get; set; }
public List<SugarParameter> Parameters { get; set; }
public List<MappingFieldsExpression> MappingExpressions { get; set; }
}
}

View File

@@ -536,7 +536,19 @@ namespace SqlSugar
var sqlObj = this.SqlBuilder.ConditionalModelToSql(conditionalModels,0);
return this.Where(sqlObj.Key, sqlObj.Value);
}
public ISugarQueryable<T> Where(List<IConditionalModel> conditionalModels, bool isWrap)
{
if (conditionalModels.IsNullOrEmpty()) return this;
var sqlObj = this.SqlBuilder.ConditionalModelToSql(conditionalModels, 0);
if (isWrap)
{
return this.Where("("+sqlObj.Key+")", sqlObj.Value);
}
else
{
return this.Where(sqlObj.Key, sqlObj.Value);
}
}
public virtual ISugarQueryable<T> Where<T2>(string whereString, object whereObj = null)
{
var whereValue = QueryBuilder.WhereInfos;

View File

@@ -12,5 +12,6 @@ namespace SqlSugar
OneToMany=2,
ManyToOne=3,
ManyToMany=4,
Dynamic=5
}
}

View File

@@ -182,7 +182,19 @@ namespace SqlSugar
reval = objReference;
return reval;
}
public static string GetMemberName(Expression expression)
{
if (expression is LambdaExpression)
{
expression = (expression as LambdaExpression).Body;
}
if (expression is UnaryExpression)
{
expression = ((UnaryExpression)expression).Operand;
}
var member = (expression as MemberExpression).Member.Name;
return member;
}
internal static object GetExpressionValue(Expression expression)
{
try

View File

@@ -55,7 +55,7 @@ namespace SqlSugar
ISugarQueryable<T> Where(Expression<Func<T, bool>> expression);
ISugarQueryable<T> Where(string whereString, object parameters = null);
ISugarQueryable<T> Where(List<IConditionalModel> conditionalModels);
ISugarQueryable<T> Where(List<IConditionalModel> conditionalModels,bool isWrap);
ISugarQueryable<T> Having(Expression<Func<T, bool>> expression);
ISugarQueryable<T> Having(string whereString, object parameters = null);

View File

@@ -97,6 +97,7 @@
<Compile Include="Abstract\FilterProvider\FilterProvider.cs" />
<Compile Include="Abstract\QueryableProvider\IncludesHelper.cs" />
<Compile Include="Abstract\QueryableProvider\Includes.cs" />
<Compile Include="Abstract\QueryableProvider\MappingFieldsHelper.cs" />
<Compile Include="Abstract\QueryableProvider\NavigatManager.cs" />
<Compile Include="Abstract\SaveableProvider\StorageableDataTable.cs" />
<Compile Include="Abstract\SugarProvider\SqlSugarCoreProvider.cs" />

View File

@@ -20,5 +20,9 @@ namespace SqlSugar
return thisValue;
}
}
public static IEnumerable<T> MappingField<T>(this IEnumerable<T> thisValue,Func<T, object> leftField, Func<object> rightField)
{
return thisValue;
}
}
}