mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	- 修复 弱类型 IBaseRepository<object> 级联操作问题;#1740
This commit is contained in:
		@@ -14,6 +14,7 @@ using Newtonsoft.Json;
 | 
				
			|||||||
using Newtonsoft.Json.Linq;
 | 
					using Newtonsoft.Json.Linq;
 | 
				
			||||||
using Npgsql;
 | 
					using Npgsql;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections;
 | 
				
			||||||
using System.Collections.Concurrent;
 | 
					using System.Collections.Concurrent;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.ComponentModel;
 | 
					using System.ComponentModel;
 | 
				
			||||||
@@ -610,72 +611,39 @@ namespace base_entity
 | 
				
			|||||||
            BaseEntity.Initialization(fsql, () => _asyncUow.Value);
 | 
					            BaseEntity.Initialization(fsql, () => _asyncUow.Value);
 | 
				
			||||||
            #endregion
 | 
					            #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Expression<Func<HzyTuple<User1, UserGroup, User1, User1, User1, User1>, bool>> where111 = null;
 | 
					            var fsql2 = fsql;
 | 
				
			||||||
            //where111 = where111.Or(a => a.t6.Sort > 10);
 | 
					            // 动态构建实体类型,树形结构,引用自身类型
 | 
				
			||||||
            var tsqlqlq1 = fsql.Select<User1, UserGroup, User1, User1, User1, User1>().Where(where111).ToSql();
 | 
					            var areaBuilder = fsql2.CodeFirst.DynamicEntity("Area", new TableAttribute { Name = "dy_area" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            areaBuilder.Property("id", typeof(int), new ColumnAttribute { IsPrimary = true })
 | 
				
			||||||
 | 
					                .Property("parentId", typeof(int?))
 | 
				
			||||||
 | 
					                .Property("name", typeof(string), new ColumnAttribute { StringLength = 30 });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // 交叉引用类型,先定义两个类型,再Build
 | 
					            // builder.TypeBuilder可作为类型被引用
 | 
				
			||||||
            var channelBuilder = fsql.CodeFirst.DynamicEntity("Channel", new TableAttribute { Name = "dm_channel" });
 | 
					            areaBuilder.Property("parent", areaBuilder.TypeBuilder, new NavigateAttribute { Bind = "parentId" })
 | 
				
			||||||
            var channelGroupBuilder = fsql.CodeFirst.DynamicEntity("ChannelGroup", new TableAttribute { Name = "dm_channel_group" });
 | 
					                .Property("children", typeof(List<>).MakeGenericType(areaBuilder.TypeBuilder), new NavigateAttribute { Bind = "parentId" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            channelBuilder.Property("id", typeof(long), new ColumnAttribute { IsPrimary = true })
 | 
					            var table = areaBuilder.Build();
 | 
				
			||||||
                .Property("name", typeof(string), new ColumnAttribute { StringLength = 30 }).Property("channelGroupId", typeof(long?), new ColumnAttribute { IsNullable = true })
 | 
					 | 
				
			||||||
                .Property("channelGroupId", typeof(long?))
 | 
					 | 
				
			||||||
                .Property("channelGroup", channelGroupBuilder.TypeBuilder, new NavigateAttribute { Bind = "channelGroupId" });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            channelGroupBuilder.Property("id", typeof(long), new ColumnAttribute { IsPrimary = true })
 | 
					 | 
				
			||||||
                .Property("name", typeof(string), new ColumnAttribute { StringLength = 30 })
 | 
					 | 
				
			||||||
                .Property("channels", typeof(List<>).MakeGenericType(channelBuilder.TypeBuilder), new NavigateAttribute { Bind = "channelGroupId" });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Build时不能立即获取TableInfo,因为类型尚未真正构建
 | 
					 | 
				
			||||||
            var channelEntityType = channelBuilder.BuildJustType();
 | 
					 | 
				
			||||||
            var channelGroupEntityType = channelGroupBuilder.BuildJustType();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // 构建后才根据实体类型获取表信息
 | 
					 | 
				
			||||||
            var channelTable = fsql.CodeFirst.GetTableByEntity(channelEntityType);
 | 
					 | 
				
			||||||
            var channelGroupTable = fsql.CodeFirst.GetTableByEntity(channelGroupEntityType);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // 迁移
 | 
					            // 迁移
 | 
				
			||||||
            fsql.CodeFirst.SyncStructure(channelEntityType, channelGroupEntityType);
 | 
					            fsql2.CodeFirst.SyncStructure(table.Type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            fsql.Delete<object>().AsType(channelEntityType).Where("1=1").ExecuteAffrows();
 | 
					            var area1 = table.CreateInstance(new Dictionary<string, object> { ["id"] = 1, ["name"] = "北京" });
 | 
				
			||||||
            fsql.Delete<object>().AsType(channelGroupEntityType).Where("1=1").ExecuteAffrows();
 | 
					            var area2 = table.CreateInstance(new Dictionary<string, object> { ["id"] = 2, ["parentId"] = 1, ["name"] = "东城区" });
 | 
				
			||||||
 | 
					            var area3 = table.CreateInstance(new Dictionary<string, object> { ["id"] = 3, ["parentId"] = 1, ["name"] = "西城区" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // 创建实体对象
 | 
					            var area1Children = Activator.CreateInstance(typeof(List<>).MakeGenericType(table.Type)) as IList;
 | 
				
			||||||
            var channelGroup = channelGroupTable.CreateInstance(new Dictionary<string, object>
 | 
					            area1Children!.Add(area2);
 | 
				
			||||||
            {
 | 
					            area1Children!.Add(area3);
 | 
				
			||||||
                ["id"] = 1,
 | 
					            table.Type.GetProperty("children")!.SetValue(area1, area1Children);
 | 
				
			||||||
                ["name"] = "央视频道",
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            var c = fsql.Insert<object>().AsType(channelGroupEntityType)
 | 
					 | 
				
			||||||
                .AppendData(channelGroup)
 | 
					 | 
				
			||||||
                .ExecuteAffrows();
 | 
					 | 
				
			||||||
            Console.WriteLine($"{c} inserted");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var channel = channelTable.CreateInstance(new Dictionary<string, object>
 | 
					            fsql2.Delete<object>().AsType(table.Type).Where("1=1").ExecuteAffrows();
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                ["id"] = 1,
 | 
					 | 
				
			||||||
                ["name"] = "CCTV-1",
 | 
					 | 
				
			||||||
                ["channelGroupId"] = 1
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            c = fsql.Insert<object>().AsType(channelEntityType)
 | 
					 | 
				
			||||||
                .AppendData(channel)
 | 
					 | 
				
			||||||
                .ExecuteAffrows();
 | 
					 | 
				
			||||||
            Console.WriteLine($"{c} inserted");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // 运行正确
 | 
					            var testRepo = fsql2.GetRepository<object>();
 | 
				
			||||||
            var list111 = fsql.Select<object>().AsType(channelGroupEntityType)
 | 
					            testRepo.AsType(table.Type);
 | 
				
			||||||
                .IncludeByPropertyName("channels")
 | 
					            testRepo.Insert(area1);
 | 
				
			||||||
                .ToList();
 | 
					            testRepo.SaveMany(area1, "children");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var repo222 = fsql.GetRepository<object>();
 | 
					 | 
				
			||||||
            repo222.AsType(channelGroupEntityType);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // 运行错误
 | 
					 | 
				
			||||||
            var list222 = repo222.Select
 | 
					 | 
				
			||||||
                .IncludeByPropertyName("channels")
 | 
					 | 
				
			||||||
                .ToList();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -826,5 +826,14 @@
 | 
				
			|||||||
            <param name="that"></param>
 | 
					            <param name="that"></param>
 | 
				
			||||||
            <returns></returns>
 | 
					            <returns></returns>
 | 
				
			||||||
        </member>
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            批量注入 Repository,可以参考代码自行调整
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="services"></param>
 | 
				
			||||||
 | 
					            <param name="globalDataFilter"></param>
 | 
				
			||||||
 | 
					            <param name="assemblies"></param>
 | 
				
			||||||
 | 
					            <returns></returns>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
    </members>
 | 
					    </members>
 | 
				
			||||||
</doc>
 | 
					</doc>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,8 +34,9 @@ namespace FreeSql
 | 
				
			|||||||
                repo = Activator.CreateInstance(typeof(DefaultRepository<,>).MakeGenericType(entityType, typeof(int)), _repo.Orm);
 | 
					                repo = Activator.CreateInstance(typeof(DefaultRepository<,>).MakeGenericType(entityType, typeof(int)), _repo.Orm);
 | 
				
			||||||
                (repo as IBaseRepository).UnitOfWork = _repo.UnitOfWork;
 | 
					                (repo as IBaseRepository).UnitOfWork = _repo.UnitOfWork;
 | 
				
			||||||
				GetRepositoryDbField(entityType, "_dbPriv").SetValue(repo, this);
 | 
									GetRepositoryDbField(entityType, "_dbPriv").SetValue(repo, this);
 | 
				
			||||||
				GetRepositoryDbField(entityType, "_asTablePriv").SetValue(repo, 
 | 
					                GetRepositoryDbField(entityType, "_asTablePriv").SetValue(repo,
 | 
				
			||||||
				    GetRepositoryDbField(_repo.EntityType, "_asTablePriv").GetValue(_repo));
 | 
					                    _repo.GetType().GetField("_asTablePriv", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(_repo));
 | 
				
			||||||
 | 
									    //GetRepositoryDbField(_repo.EntityType, "_asTablePriv").GetValue(_repo));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (typeof(IBaseRepository<>).MakeGenericType(_repo.EntityType).IsAssignableFrom(_repo.GetType()))
 | 
					                if (typeof(IBaseRepository<>).MakeGenericType(_repo.EntityType).IsAssignableFrom(_repo.GetType()))
 | 
				
			||||||
                    typeof(RepositoryDbContext).GetMethod("SetRepositoryDataFilter").MakeGenericMethod(_repo.EntityType)
 | 
					                    typeof(RepositoryDbContext).GetMethod("SetRepositoryDataFilter").MakeGenericMethod(_repo.EntityType)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user