This commit is contained in:
sunkaixuan 2022-04-11 20:54:20 +08:00
parent 2943c46c27
commit 88d3df0331
10 changed files with 194 additions and 76 deletions

View File

@ -16,10 +16,12 @@ namespace OrmTest
var db = NewUnitTest.Db;
db.CodeFirst.InitTables<StudentA, RoomA, SchoolA, TeacherA>();
db.CodeFirst.InitTables<BookA>();
db.DbMaintenance.TruncateTable<StudentA>();
db.DbMaintenance.TruncateTable<RoomA>();
db.DbMaintenance.TruncateTable<SchoolA>();
db.DbMaintenance.TruncateTable<TeacherA>();
db.DbMaintenance.TruncateTable<BookA>();
db.Insertable(new RoomA() { RoomId = 1, RoomName = "北大001室", SchoolId = 1 }).ExecuteCommand();
db.Insertable(new RoomA() { RoomId = 2, RoomName = "北大002室", SchoolId = 1 }).ExecuteCommand();
db.Insertable(new RoomA() { RoomId = 3, RoomName = "北大003室", SchoolId = 1 }).ExecuteCommand();
@ -42,6 +44,13 @@ namespace OrmTest
db.Insertable(new TeacherA() { SchoolId = 2, Id = 3, Name = "清华老师01" }).ExecuteCommand();
db.Insertable(new TeacherA() { SchoolId = 2, Id = 4, Name = "清华老师02" }).ExecuteCommand();
db.Insertable(new BookA() { BookId=1, Name="java" , studenId=1 }).ExecuteCommand();
db.Insertable(new BookA() { BookId = 2, Name = "c#2", studenId = 2 }).ExecuteCommand();
db.Insertable(new BookA() { BookId = 3, Name = "c#1", studenId = 2 }).ExecuteCommand();
db.Insertable(new BookA() { BookId = 4, Name = "php", studenId = 3 }).ExecuteCommand();
db.Insertable(new BookA() { BookId = 5, Name = "js", studenId = 4 }).ExecuteCommand();
//先用Mapper导航映射查出第二层
var list = db.Queryable<StudentA>().Mapper(x => x.SchoolA, x => x.SchoolId).ToList();
@ -55,25 +64,49 @@ namespace OrmTest
sch.TeacherList = db.Queryable<TeacherA>().SetContext(teachera => teachera.SchoolId, () => sch.SchoolId, sch).ToList();
});
db.Queryable<StudentA>()
var list2=db.Queryable<StudentA>()
.Includes(x => x.SchoolA, x => x.RoomList)//2个参数就是 then Include
.Includes(x => x.Books)
.ToList();
var list3= db.Queryable<A>().Includes(x => x.BList).ToList();
}
public class ABMapping
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int AId { get; set; }
public int BId { get; set; }
}
public class A
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
public string Name { get; set; }
[Navigat(typeof(ABMapping),nameof(ABMapping.AId),nameof(ABMapping.BId))]
public List<B> BList { get; set; }
}
public class B
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
public string Name { get; set; }
[Navigat(typeof(ABMapping), nameof(ABMapping.BId), nameof(ABMapping.AId))]
public List<A> BList { get; set; }
}
public class StudentA
{
[SugarColumn(IsPrimaryKey = true)]
public int StudentId { get; set; }
public string Name { get; set; }
public int SchoolId { get; set; }
[Navigat(nameof(SchoolId))]
[Navigat(NavigatType.OneToOne, nameof(SchoolId))]
public SchoolA SchoolA { get; set; }
[Navigat(nameof(BookA.studenId))]
[Navigat(NavigatType.OneToMany, nameof(BookA.studenId))]
public List<BookA> Books { get; set; }
}
}
public class SchoolA
{
[SugarColumn(IsPrimaryKey = true)]
@ -100,6 +133,10 @@ namespace OrmTest
}
public class BookA
{
[SugarColumn(IsPrimaryKey = true)]
public int BookId { get; set; }
public string Name { get; set; }
public int studenId { get; set; }
}

View File

@ -10,6 +10,7 @@ namespace SqlSugar
public partial class QueryableProvider<T> : QueryableAccessory, ISugarQueryable<T>
{
public ISugarQueryable<T> Includes<TReturn1>(Expression<Func<T, TReturn1>> include1) { _Includes<T, TReturn1>(this.Context, include1); return this; }
public ISugarQueryable<T> Includes<TReturn1>(Expression<Func<T, List<TReturn1>>> include1) { _Includes<T, TReturn1>(this.Context, include1); return this; }
public ISugarQueryable<T> Includes<TReturn1, TReturn2>(Expression<Func<T, List<TReturn1>>> include1, Expression<Func<TReturn1, TReturn2>> include2) { _Includes<T, TReturn1, TReturn2>(this.Context, include1, include2); return this; }
public ISugarQueryable<T> Includes<TReturn1, TReturn2>(Expression<Func<T, TReturn1>> include1, Expression<Func<TReturn1, TReturn2>> include2) { _Includes<T, TReturn1, TReturn2>(this.Context, include1, include2); return this; }
public ISugarQueryable<T> Includes<TReturn1, TReturn2, TReturn3>(Expression<Func<T, TReturn1>> include1, Expression<Func<TReturn1, TReturn2>> include2, Expression<Func<TReturn2, TReturn3>> include3) { _Includes<T, TReturn1, TReturn2, TReturn3>(this.Context, include1, include2, include3); return this; }

View File

@ -11,36 +11,29 @@ namespace SqlSugar
{
private void _Includes<T1, TReturn1>(SqlSugarProvider context, params Expression[] expressions)
{
Action<ISugarQueryable<object>> SelectR1 = it => it.Select<TReturn1>();
Func<ISugarQueryable<object>,List<object>> SelectR1 = it => it.Select<TReturn1>().ToList().Select(x=>x as object).ToList();
var navigat = new NavigatManager<T>();
navigat.SelectR1 = SelectR1;
navigat.Expressions = expressions;
navigat.Context = this.Context;
this.QueryBuilder.Includes = navigat;
if (this.QueryBuilder.Includes == null) this.QueryBuilder.Includes = new List<object>();
this.QueryBuilder.Includes.Add(navigat);
}
private void _Includes<T1, TReturn1, TReturn2>(SqlSugarProvider context, params Expression[] expressions)
{
Action<ISugarQueryable<object>> SelectR1 = it => it.Select<TReturn1>();
Action<ISugarQueryable<object>> SelectR2 = it => it.Select<TReturn2>();
Func<ISugarQueryable<object>, List<object>> SelectR1 = it => it.Select<TReturn1>().ToList().Select(x => x as object).ToList();
Func<ISugarQueryable<object>, List<object>> SelectR2 = it => it.Select<TReturn2>().ToList().Select(x => x as object).ToList();
var navigat = new NavigatManager<T>();
navigat.SelectR1 = SelectR1;
navigat.SelectR2 = SelectR2;
navigat.Expressions = expressions;
navigat.Context = this.Context;
this.QueryBuilder.Includes = navigat;
if (this.QueryBuilder.Includes == null) this.QueryBuilder.Includes = new List<object>();
this.QueryBuilder.Includes.Add(navigat);
}
private void _Includes<T1, TReturn1, TReturn2, TReturn3>(SqlSugarProvider context, params Expression[] expressions)
{
Action<ISugarQueryable<object>> SelectR1 = it => it.Select<TReturn1>();
Action<ISugarQueryable<object>> SelectR2 = it => it.Select<TReturn2>();
Action<ISugarQueryable<object>> SelectR3 = it => it.Select<TReturn3>();
var navigat = new NavigatManager<T>();
navigat.SelectR1 = SelectR1;
navigat.SelectR2 = SelectR2;
navigat.SelectR2 = SelectR3;
navigat.Expressions = expressions;
navigat.Context = this.Context;
this.QueryBuilder.Includes = navigat;
throw new NotImplementedException();
}
private void _Includes<T1, TReturn1, TReturn2, TReturn3, TReturn4>(SqlSugarProvider context, params Expression[] expressions)
{

View File

@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
@ -10,14 +11,14 @@ namespace SqlSugar
public class NavigatManager<T>
{
public SqlSugarProvider Context { get; set; }
public Action<ISugarQueryable<object>> SelectR1 { get; set; }
public Action<ISugarQueryable<object>> SelectR2 { get; set; }
public Action<ISugarQueryable<object>> SelectR3 { get; set; }
public Action<ISugarQueryable<object>> SelectR4 { get; set; }
public Action<ISugarQueryable<object>> SelectR5 { get; set; }
public Action<ISugarQueryable<object>> SelectR6 { get; set; }
public Action<ISugarQueryable<object>> SelectR7 { get; set; }
public Action<ISugarQueryable<object>> SelectR8 { get; set; }
public Func<ISugarQueryable<object>, List<object>> SelectR1 { get; set; }
public Func<ISugarQueryable<object>, List<object>> SelectR2 { get; set; }
public Func<ISugarQueryable<object>, List<object>> SelectR3 { get; set; }
public Func<ISugarQueryable<object>, List<object>> SelectR4 { get; set; }
public Func<ISugarQueryable<object>, List<object>> SelectR5 { get; set; }
public Func<ISugarQueryable<object>, List<object>> SelectR6 { get; set; }
public Func<ISugarQueryable<object>, List<object>> SelectR7 { get; set; }
public Func<ISugarQueryable<object>, List<object>> SelectR8 { get; set; }
public Expression[] Expressions { get; set; }
public List<T> RootList { get; set; }
//public QueryableProvider<T> Queryable { get; set; }
@ -28,50 +29,112 @@ namespace SqlSugar
//private EntityInfo _entityInfo;
public void Execute()
{
var i = 1;
foreach (var item in Expressions)
{
ExecuteByLay(i, item);
i++;
}
}
private void ExecuteByLay(int i, Expression item)
{
if (i == 1)
{
ExecuteByLay(item, RootList.Select(it => it as object).ToList(), SelectR1);
}
}
private void ExecuteByLay(Expression expression, List<object> list, Func<ISugarQueryable<object>, List<object>> selector)
{
if (list == null || list.Count == 0) return;
var memberExpression = ((expression as LambdaExpression).Body as MemberExpression);
var listItemType = list[0].GetType();
var listItemEntity = this.Context.EntityMaintenance.GetEntityInfo(listItemType);
var listPkColumn = listItemEntity.Columns.Where(it => it.IsPrimarykey).FirstOrDefault();
var navObjectName = memberExpression.Member.Name;
var navObjectNamePropety = listItemType.GetProperty(navObjectName);
var navObjectNameColumnInfo = listItemEntity.Columns.First(it => it.PropertyName == navObjectName);
Check.ExceptionEasy(navObjectNameColumnInfo.Navigat == null, $"{navObjectName} not [Navigat(..)] ", $"{navObjectName} 没有导航特性 [Navigat(..)] ");
if (navObjectNameColumnInfo.Navigat.NavigatType == NavigatType.OneToOne)
{
OneToOne(list, selector, listItemEntity, navObjectNamePropety, navObjectNameColumnInfo);
}
else if (navObjectNameColumnInfo.Navigat.NavigatType == NavigatType.OneToMany)
{
OneToMany(list, selector, listItemEntity, navObjectNamePropety, navObjectNameColumnInfo);
}
else if (navObjectNameColumnInfo.Navigat.NavigatType == NavigatType.ManyToOne)
{
}
else
{
}
}
//private void Lay1(List<Expression> preExpressionList, Expression expression, List<object> list)
//{
// if (list == null || list.Count == 0) return;
// var memberExpression = ((expression as LambdaExpression).Body as MemberExpression);
// var navName = memberExpression.Member.Name;
// var type = list[0].GetType();
// var propety = type.GetProperty(navName);
// var entity=this.Context.EntityMaintenance.GetEntityInfo(type);
// var columInfo = entity.Columns.First(it => it.PropertyName == navName);
// Check.ExceptionEasy(columInfo.Navigat == null, $"{navName} not [Navigat(..)] ", $"{navName} 没有导航特性 [Navigat(..)] ");
// var navColumn = entity.Columns.FirstOrDefault(it => it.PropertyName == columInfo.Navigat.Name);
// if (columInfo.Navigat.MappingType != null)
// {
private void OneToOne(List<object> list, Func<ISugarQueryable<object>, List<object>> selector, EntityInfo listItemEntity, System.Reflection.PropertyInfo navObjectNamePropety, EntityColumnInfo navObjectNameColumnInfo)
{
var navColumn = listItemEntity.Columns.FirstOrDefault(it => it.PropertyName == navObjectNameColumnInfo.Navigat.Name);
var navType = navObjectNamePropety.PropertyType;
var navEntityInfo = this.Context.EntityMaintenance.GetEntityInfo(navType);
var navPkColumn = navEntityInfo.Columns.Where(it => it.IsPrimarykey).FirstOrDefault();
// }
// else if (columInfo.Navigat.Name.Contains("."))
// {
var ids = list.Select(it => it.GetType().GetProperty(navObjectNameColumnInfo.Navigat.Name).GetValue(it)).Select(it => it == null ? "null" : it).Distinct().ToList();
List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
conditionalModels.Add((new ConditionalModel()
{
ConditionalType = ConditionalType.In,
FieldName = navPkColumn.DbColumnName,
FieldValue = String.Join(",", ids),
CSharpTypeName = navObjectNameColumnInfo.PropertyInfo.PropertyType.Name
}));
var navList = selector(this.Context.Queryable<object>().AS(navEntityInfo.DbTableName).Where(conditionalModels));
foreach (var item in list)
{
var setValue = navList.FirstOrDefault(x => navPkColumn.PropertyInfo.GetValue(x).ObjToString() == navColumn.PropertyInfo.GetValue(item).ObjToString());
navObjectNamePropety.SetValue(item, setValue);
}
}
private void OneToMany(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 navColumn = navEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == navObjectNameColumnInfo.Navigat.Name);
//var navType = navObjectNamePropety.PropertyType;
var listItemPkColumn = listItemEntity.Columns.Where(it => it.IsPrimarykey).FirstOrDefault();
var ids = list.Select(it => it.GetType().GetProperty(listItemPkColumn.PropertyName).GetValue(it)).Select(it => it == null ? "null" : it).Distinct().ToList();
List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
conditionalModels.Add((new ConditionalModel()
{
ConditionalType = ConditionalType.In,
FieldName = navObjectNameColumnInfo.Navigat.Name,
FieldValue = String.Join(",", ids),
CSharpTypeName = listItemPkColumn.PropertyInfo.PropertyType.Name
}));
var navList = selector(this.Context.Queryable<object>().AS(navEntityInfo.DbTableName).Where(conditionalModels));
if (navList.HasValue())
foreach (var item in list)
{
var setValue = navList
.Where(x => navColumn.PropertyInfo.GetValue(x).ObjToString() == listItemPkColumn.PropertyInfo.GetValue(item).ObjToString()).ToList();
var instance = Activator.CreateInstance(navObjectNamePropety.PropertyType, true);
var ilist = instance as IList;
foreach (var value in setValue)
{
ilist.Add(value);
}
navObjectNamePropety.SetValue(item, instance);
}
}
// }
// else
// {
// var tableType =this.Context.EntityMaintenance.GetEntityInfo(list.First().GetType());
// var pkColumn = tableType.Columns.Where(it=>it.IsPrimarykey).FirstOrDefault();
// var ids = list.Select(it => it.GetType().GetProperty(navColumn.PropertyName).GetValue(it)).Select(it=>it==null?"null":it).Distinct().ToList();
// List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
// conditionalModels.Add((new ConditionalModel() {
// ConditionalType = ConditionalType.In,
// FieldName= pkColumn.DbColumnName,
// FieldValue=String.Join(",", ids),
// CSharpTypeName=columInfo.PropertyInfo.PropertyType.Name
// }));
// var list2 = this.Context.Queryable<object>().AS(tableType.DbTableName).Where(conditionalModels).ToList();
// foreach (var item in list)
// {
// item.
// }
// }
//}
//private void Lay2(List<Expression> preExpressionList, List<T> list)
//{

View File

@ -2215,9 +2215,13 @@ namespace SqlSugar
{
if (this.QueryBuilder.Includes != null)
{
var manager=(this.QueryBuilder.Includes as NavigatManager<TResult>);
manager.RootList = result;
manager.Execute();
var managers=(this.QueryBuilder.Includes as List<object>);
foreach (var it in managers)
{
var manager = it as NavigatManager<TResult>;
manager.RootList = result;
manager.Execute();
}
}
}

View File

@ -33,7 +33,7 @@ namespace SqlSugar
#endregion
#region Splicing basic
public object Includes { get; set; }
public List<object> Includes { get; set; }
public List<string> IgnoreColumns { get; set; }
public bool IsCount { get; set; }
public bool IsSqlQuery { get; set; }

View File

@ -210,15 +210,17 @@ namespace SqlSugar
public Type MappingType { get; set; }
public string MappingAId { get; set; }
public string MappingBId { get; set; }
public Navigat(string name)
public NavigatType NavigatType { get; set; }
public Navigat(NavigatType navigatType,string name)
{
this.Name = name;
this.NavigatType = navigatType;
}
public Navigat(Type abType,string aId,string bId)
public Navigat(Type MappingTableType,string typeAiD,string typeBId)
{
this.MappingType = abType;
this.MappingAId = aId;
this.MappingBId = bId;
this.MappingType = MappingTableType;
this.MappingAId = typeAiD;
this.MappingBId = typeBId;
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SqlSugar
{
public enum NavigatType
{
OneToOne=1,
OneToMany=2,
ManyToOne=3,
ManyToMany=4,
}
}

View File

@ -14,6 +14,7 @@ namespace SqlSugar
public partial interface ISugarQueryable<T>
{
ISugarQueryable<T> Includes<TReturn1>(Expression<Func<T, TReturn1>> include1);
ISugarQueryable<T> Includes<TReturn1>(Expression<Func<T, List<TReturn1>>> include1);
ISugarQueryable<T> Includes<TReturn1, TReturn2>(Expression<Func<T, TReturn1>> include1, Expression<Func<TReturn1, TReturn2>> include2);
ISugarQueryable<T> Includes<TReturn1, TReturn2>(Expression<Func<T, List<TReturn1>>> include1, Expression<Func<TReturn1, TReturn2>> include2);
ISugarQueryable<T> Includes<TReturn1, TReturn2, TReturn3>(Expression<Func<T, TReturn1>> include1, Expression<Func<TReturn1, List<TReturn2>>> include2, Expression<Func<TReturn2, TReturn3>> include3);

View File

@ -100,6 +100,7 @@
<Compile Include="Abstract\SaveableProvider\StorageableDataTable.cs" />
<Compile Include="Abstract\SugarProvider\SqlSugarCoreProvider.cs" />
<Compile Include="Entities\JoinMapper.cs" />
<Compile Include="Enum\NavigatType.cs" />
<Compile Include="Enum\SugarActionType.cs" />
<Compile Include="Entities\SugarConnection.cs" />
<Compile Include="ExpressionsToSql\Subquery\SubTemplate.cs" />