mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2026-02-27 16:50:33 +08:00
Synchronization code
This commit is contained in:
@@ -0,0 +1,35 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SqlSugar
|
||||||
|
{
|
||||||
|
public static class DynamicBuilderHelper
|
||||||
|
{
|
||||||
|
public static Type CreateDynamicClass(string className, List<PropertyMetadata> properties, TypeAttributes attributes = TypeAttributes.Public, List<CustomAttributeBuilder> classCustomAttributes = null, Type baseType = null, Type[] interfaces = null)
|
||||||
|
{
|
||||||
|
TypeBuilder typeBuilder = EmitTool.CreateTypeBuilder(className, attributes, baseType, interfaces);
|
||||||
|
|
||||||
|
if (classCustomAttributes != null)
|
||||||
|
{
|
||||||
|
foreach (var attributeBuilder in classCustomAttributes)
|
||||||
|
{
|
||||||
|
typeBuilder.SetCustomAttribute(attributeBuilder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (PropertyMetadata property in properties)
|
||||||
|
{
|
||||||
|
EmitTool.CreateProperty(typeBuilder, property.Name, property.Type, property.CustomAttributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
Type dynamicType = typeBuilder.CreateTypeInfo().AsType();
|
||||||
|
|
||||||
|
return dynamicType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace SqlSugar
|
||||||
|
{
|
||||||
|
|
||||||
|
public class DynamicProperyBuilder
|
||||||
|
{
|
||||||
|
private bool IsCache = false;
|
||||||
|
public static DynamicProperyBuilder CopyNew()
|
||||||
|
{
|
||||||
|
return new DynamicProperyBuilder();
|
||||||
|
}
|
||||||
|
public DynamicBuilder baseBuilder;
|
||||||
|
public DynamicProperyBuilder CreateProperty(string propertyName, Type properyType, SugarColumn table)
|
||||||
|
{
|
||||||
|
PropertyMetadata addItem = new PropertyMetadata();
|
||||||
|
addItem.Name = propertyName;
|
||||||
|
addItem.Type = properyType;
|
||||||
|
addItem.CustomAttributes = new List<CustomAttributeBuilder>() { baseBuilder.GetProperty(table) };
|
||||||
|
baseBuilder.propertyAttr.Add(addItem);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public DynamicProperyBuilder WithCache(bool isCache=true)
|
||||||
|
{
|
||||||
|
IsCache = isCache;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public Type BuilderType()
|
||||||
|
{
|
||||||
|
if (IsCache)
|
||||||
|
{
|
||||||
|
var key = baseBuilder.entityName + string.Join("_", baseBuilder.propertyAttr.Select(it => it.Name + it.Type.Name));
|
||||||
|
return new ReflectionInoCacheService().GetOrCreate(key,() =>
|
||||||
|
{
|
||||||
|
var result = DynamicBuilderHelper.CreateDynamicClass(baseBuilder.entityName, baseBuilder.propertyAttr, TypeAttributes.Public, baseBuilder.entityAttr, baseBuilder.baseType, baseBuilder.interfaces);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var result = DynamicBuilderHelper.CreateDynamicClass(baseBuilder.entityName, baseBuilder.propertyAttr, TypeAttributes.Public, baseBuilder.entityAttr, baseBuilder.baseType, baseBuilder.interfaces);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SqlSugar
|
||||||
|
{
|
||||||
|
internal class EmitTool
|
||||||
|
{
|
||||||
|
internal static ModuleBuilder CreateModuleBuilder()
|
||||||
|
{
|
||||||
|
AssemblyBuilder assemblyBuilder = CreateAssembly();
|
||||||
|
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicModule");
|
||||||
|
return moduleBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static AssemblyBuilder CreateAssembly()
|
||||||
|
{
|
||||||
|
AssemblyName assemblyName = new AssemblyName($"DynamicAssembly_{Guid.NewGuid():N}");
|
||||||
|
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndCollect);
|
||||||
|
return assemblyBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static TypeBuilder CreateTypeBuilder(string className, TypeAttributes attributes, Type baseType, Type[] interfaces)
|
||||||
|
{
|
||||||
|
ModuleBuilder moduleBuilder = EmitTool.CreateModuleBuilder();
|
||||||
|
TypeBuilder typeBuilder = moduleBuilder.DefineType(className, attributes, baseType, interfaces);
|
||||||
|
return typeBuilder;
|
||||||
|
}
|
||||||
|
internal static PropertyBuilder CreateProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType, IEnumerable<CustomAttributeBuilder> propertyCustomAttributes = null)
|
||||||
|
{
|
||||||
|
FieldBuilder fieldBuilder = typeBuilder.DefineField($"_{propertyName}", propertyType, FieldAttributes.Private);
|
||||||
|
|
||||||
|
PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.None, propertyType, null);
|
||||||
|
|
||||||
|
MethodBuilder getterBuilder = typeBuilder.DefineMethod($"get_{propertyName}", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
|
||||||
|
ILGenerator getterIL = getterBuilder.GetILGenerator();
|
||||||
|
getterIL.Emit(OpCodes.Ldarg_0);
|
||||||
|
getterIL.Emit(OpCodes.Ldfld, fieldBuilder);
|
||||||
|
getterIL.Emit(OpCodes.Ret);
|
||||||
|
|
||||||
|
MethodBuilder setterBuilder = typeBuilder.DefineMethod($"set_{propertyName}", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { propertyType });
|
||||||
|
ILGenerator setterIL = setterBuilder.GetILGenerator();
|
||||||
|
setterIL.Emit(OpCodes.Ldarg_0);
|
||||||
|
setterIL.Emit(OpCodes.Ldarg_1);
|
||||||
|
setterIL.Emit(OpCodes.Stfld, fieldBuilder);
|
||||||
|
setterIL.Emit(OpCodes.Ret);
|
||||||
|
|
||||||
|
propertyBuilder.SetGetMethod(getterBuilder);
|
||||||
|
propertyBuilder.SetSetMethod(setterBuilder);
|
||||||
|
|
||||||
|
if (propertyCustomAttributes != null)
|
||||||
|
{
|
||||||
|
foreach (var attributeBuilder in propertyCustomAttributes)
|
||||||
|
{
|
||||||
|
propertyBuilder.SetCustomAttribute(attributeBuilder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return propertyBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
78
Src/Asp.NetCore2/SqlSugar/Abstract/DynamicBuilder/Helper.cs
Normal file
78
Src/Asp.NetCore2/SqlSugar/Abstract/DynamicBuilder/Helper.cs
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SqlSugar
|
||||||
|
{
|
||||||
|
public partial class DynamicBuilder
|
||||||
|
{
|
||||||
|
internal CustomAttributeBuilder GetEntity(SugarTable sugarTable)
|
||||||
|
{
|
||||||
|
Type attributeType = typeof(SugarTable);
|
||||||
|
ConstructorInfo attributeCtor = attributeType.GetConstructor(new Type[] { typeof(string) });
|
||||||
|
CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(attributeCtor, new object[] { "" },
|
||||||
|
new PropertyInfo[] {
|
||||||
|
attributeType.GetProperty(nameof(SugarTable.TableName)),
|
||||||
|
attributeType.GetProperty(nameof(SugarTable.TableDescription)) ,
|
||||||
|
attributeType.GetProperty(nameof(SugarTable.IsDisabledUpdateAll)) ,
|
||||||
|
attributeType.GetProperty(nameof(SugarTable.IsDisabledDelete))
|
||||||
|
}
|
||||||
|
, new object[] {
|
||||||
|
sugarTable.TableName,
|
||||||
|
sugarTable.TableDescription ,
|
||||||
|
sugarTable.IsDisabledUpdateAll,
|
||||||
|
sugarTable.IsDisabledDelete
|
||||||
|
});
|
||||||
|
return attributeBuilder;
|
||||||
|
}
|
||||||
|
internal CustomAttributeBuilder GetProperty(SugarColumn sugarTable)
|
||||||
|
{
|
||||||
|
Type attributeType = typeof(SugarColumn);
|
||||||
|
ConstructorInfo attributeCtor = attributeType.GetConstructor(new Type[] { });
|
||||||
|
CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(attributeCtor, new object[] { },
|
||||||
|
new PropertyInfo[] {
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.IsPrimaryKey)),
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.IsIdentity)),
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.DefaultValue)),
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.Length)),
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.DecimalDigits)),
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.ColumnDataType)),
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.IsNullable)),
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.ColumnDescription)),
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.OracleSequenceName)),
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.IsIgnore)),
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.IsJson)),
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.IsOnlyIgnoreInsert)),
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.IsOnlyIgnoreUpdate)),
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.OldColumnName)),
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.SqlParameterDbType)),
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.SqlParameterSize)),
|
||||||
|
attributeType.GetProperty(nameof(SugarColumn.IsArray))
|
||||||
|
}
|
||||||
|
, new object[] {
|
||||||
|
sugarTable.IsPrimaryKey,
|
||||||
|
sugarTable.IsIdentity,
|
||||||
|
sugarTable.DefaultValue,
|
||||||
|
sugarTable.Length,
|
||||||
|
sugarTable.DecimalDigits,
|
||||||
|
sugarTable.ColumnDataType,
|
||||||
|
sugarTable.IsNullable,
|
||||||
|
sugarTable.ColumnDescription,
|
||||||
|
sugarTable.OracleSequenceName,
|
||||||
|
sugarTable.IsIgnore,
|
||||||
|
sugarTable.IsJson,
|
||||||
|
sugarTable.IsOnlyIgnoreInsert,
|
||||||
|
sugarTable.IsOnlyIgnoreUpdate,
|
||||||
|
sugarTable.OldColumnName,
|
||||||
|
sugarTable.SqlParameterDbType,
|
||||||
|
sugarTable.SqlParameterSize,
|
||||||
|
sugarTable.IsArray
|
||||||
|
});
|
||||||
|
return attributeBuilder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
67
Src/Asp.NetCore2/SqlSugar/Abstract/DynamicBuilder/Master.cs
Normal file
67
Src/Asp.NetCore2/SqlSugar/Abstract/DynamicBuilder/Master.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Security.AccessControl;
|
||||||
|
|
||||||
|
namespace SqlSugar
|
||||||
|
{
|
||||||
|
public partial class DynamicBuilder
|
||||||
|
{
|
||||||
|
internal List<PropertyMetadata> propertyAttr = new List<PropertyMetadata>();
|
||||||
|
internal List<CustomAttributeBuilder> entityAttr = new List<CustomAttributeBuilder>();
|
||||||
|
internal string entityName { get; set; }
|
||||||
|
internal Type baseType = null;
|
||||||
|
internal Type[] interfaces = null;
|
||||||
|
internal SqlSugarProvider context;
|
||||||
|
|
||||||
|
public DynamicBuilder(SqlSugarProvider context)
|
||||||
|
{
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DynamicProperyBuilder CreateClass(string entityName, SugarTable table, Type baseType = null, Type[] interfaces = null)
|
||||||
|
{
|
||||||
|
this.baseType = baseType;
|
||||||
|
this.interfaces = interfaces;
|
||||||
|
this.entityName = entityName;
|
||||||
|
this.entityAttr = new List<CustomAttributeBuilder>() { GetEntity(table) };
|
||||||
|
return new DynamicProperyBuilder() { baseBuilder=this};
|
||||||
|
}
|
||||||
|
|
||||||
|
public object CreateObjectByType(Type type, Dictionary<string, object> dict)
|
||||||
|
{
|
||||||
|
// 创建一个默认的空对象
|
||||||
|
object obj = Activator.CreateInstance(type);
|
||||||
|
|
||||||
|
// 遍历字典中的每个 key-value 对
|
||||||
|
foreach (KeyValuePair<string, object> pair in dict)
|
||||||
|
{
|
||||||
|
// 获取对象中的属性
|
||||||
|
PropertyInfo propertyInfo = type.GetProperty(pair.Key);
|
||||||
|
|
||||||
|
if (propertyInfo != null)
|
||||||
|
{
|
||||||
|
// 如果找到了该属性,则将其值设置为字典中对应的值
|
||||||
|
propertyInfo.SetValue(obj, Convert.ChangeType(pair.Value, propertyInfo.PropertyType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回创建的对象
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<object> CreateObjectByType(Type type, List<Dictionary<string, object>> dictList)
|
||||||
|
{
|
||||||
|
List<object> result = new List<object>();
|
||||||
|
foreach (var item in dictList)
|
||||||
|
{
|
||||||
|
result.Add(CreateObjectByType(type, item));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -155,6 +155,10 @@ namespace SqlSugar
|
|||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
if (entityType.Assembly.IsDynamic&& entityType.Assembly.FullName.StartsWith("Dynamic"))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
var path = entityType.Assembly.Location;
|
var path = entityType.Assembly.Location;
|
||||||
if (string.IsNullOrEmpty(path))
|
if (string.IsNullOrEmpty(path))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1624,6 +1624,10 @@ namespace SqlSugar
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Other
|
#region Other
|
||||||
|
public DynamicBuilder DynamicBuilder()
|
||||||
|
{
|
||||||
|
return new DynamicBuilder(this.Context);
|
||||||
|
}
|
||||||
public void Tracking<T>(T data) where T : class, new()
|
public void Tracking<T>(T data) where T : class, new()
|
||||||
{
|
{
|
||||||
if (data != null)
|
if (data != null)
|
||||||
|
|||||||
@@ -786,6 +786,10 @@ namespace SqlSugar
|
|||||||
{
|
{
|
||||||
return new SqlSugarClient(UtilMethods.CopyConfig(this.Ado.Context.CurrentConnectionConfig));
|
return new SqlSugarClient(UtilMethods.CopyConfig(this.Ado.Context.CurrentConnectionConfig));
|
||||||
}
|
}
|
||||||
|
public DynamicBuilder DynamicBuilder()
|
||||||
|
{
|
||||||
|
return ScopedContext.DynamicBuilder();
|
||||||
|
}
|
||||||
public void Tracking<T>(T data) where T : class, new()
|
public void Tracking<T>(T data) where T : class, new()
|
||||||
{
|
{
|
||||||
ScopedContext.Tracking(data);
|
ScopedContext.Tracking(data);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace SqlSugar
|
|||||||
{
|
{
|
||||||
[AttributeUsage(AttributeTargets.Class, Inherited = true)]
|
[AttributeUsage(AttributeTargets.Class, Inherited = true)]
|
||||||
public class SugarTable : Attribute {
|
public class SugarTable : Attribute {
|
||||||
private SugarTable() { }
|
public SugarTable() { }
|
||||||
public string TableName { get; set; }
|
public string TableName { get; set; }
|
||||||
public string TableDescription { get; set; }
|
public string TableDescription { get; set; }
|
||||||
public bool IsDisabledDelete { get; set; }
|
public bool IsDisabledDelete { get; set; }
|
||||||
|
|||||||
16
Src/Asp.NetCore2/SqlSugar/Entities/PropertyMetadata.cs
Normal file
16
Src/Asp.NetCore2/SqlSugar/Entities/PropertyMetadata.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SqlSugar
|
||||||
|
{
|
||||||
|
public class PropertyMetadata
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public Type Type { get; set; }
|
||||||
|
public IEnumerable<CustomAttributeBuilder> CustomAttributes { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -45,6 +45,7 @@ namespace SqlSugar
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Other methods
|
#region Other methods
|
||||||
|
DynamicBuilder DynamicBuilder();
|
||||||
void Tracking<T>(T data) where T : class, new();
|
void Tracking<T>(T data) where T : class, new();
|
||||||
void Tracking<T>(List<T> data) where T : class, new();
|
void Tracking<T>(List<T> data) where T : class, new();
|
||||||
SqlSugarClient CopyNew();
|
SqlSugarClient CopyNew();
|
||||||
|
|||||||
@@ -1156,6 +1156,10 @@ namespace SqlSugar
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Other method
|
#region Other method
|
||||||
|
public DynamicBuilder DynamicBuilder()
|
||||||
|
{
|
||||||
|
return this.Context.DynamicBuilder();
|
||||||
|
}
|
||||||
public void Tracking<T>(T data) where T : class, new()
|
public void Tracking<T>(T data) where T : class, new()
|
||||||
{
|
{
|
||||||
this.Context.Tracking(data);
|
this.Context.Tracking(data);
|
||||||
|
|||||||
@@ -835,6 +835,10 @@ namespace SqlSugar
|
|||||||
{
|
{
|
||||||
return new SqlSugarClient(UtilMethods.CopyConfig(this.Ado.Context.CurrentConnectionConfig));
|
return new SqlSugarClient(UtilMethods.CopyConfig(this.Ado.Context.CurrentConnectionConfig));
|
||||||
}
|
}
|
||||||
|
public DynamicBuilder DynamicBuilder()
|
||||||
|
{
|
||||||
|
return ScopedContext.DynamicBuilder();
|
||||||
|
}
|
||||||
public void Tracking<T>(T data) where T : class, new()
|
public void Tracking<T>(T data) where T : class, new()
|
||||||
{
|
{
|
||||||
ScopedContext.Tracking(data);
|
ScopedContext.Tracking(data);
|
||||||
|
|||||||
Reference in New Issue
Block a user