mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2025-11-09 02:44:58 +08:00
Support NavigateType.Dynamic
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -12,5 +12,6 @@ namespace SqlSugar
|
||||
OneToMany=2,
|
||||
ManyToOne=3,
|
||||
ManyToMany=4,
|
||||
Dynamic=5
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user