Skip to content

Commit

Permalink
Merge pull request #1593 from d4ilys/master
Browse files Browse the repository at this point in the history
修复DynamicEntity特性构造函数实例化问题
  • Loading branch information
2881099 authored Aug 17, 2023
2 parents eea1d46 + c9aa335 commit 2164493
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 8 deletions.
43 changes: 43 additions & 0 deletions FreeSql.Tests/FreeSql.Tests/DynamicEntity/DynamicEntityTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,51 @@ public void DefaultValueTest()
fsql.Insert<object>().AsType(table.Type).AppendData(instance).ExecuteAffrows();
var objects = fsql.Select<object>().AsType(table.Type).ToList();
}

[Fact]
public void Issue1591Test()
{
var backupTableName = "test";
var newTableName = "new_test";
var key = "index_key";
var columns = new List<string>()
{
"Name",
"Tid"
};
var attributes = new List<Attribute>();
attributes.Add(new TableAttribute() { Name = newTableName });

var indexName = key.ToUpper().Replace(backupTableName.ToUpper(), newTableName.ToUpper());
var indexFields = string.Join(",", columns.Select(c => c));
var indexAttribute = new IndexAttribute(indexName, indexFields
, false);
attributes.Add(indexAttribute);

var table = fsql.CodeFirst.DynamicEntity("AttributeUsers", attributes.ToArray())
.Property("Id", typeof(int),
new ColumnAttribute() { IsPrimary = true, IsIdentity = true, Position = 1 })
.Property("Name", typeof(string),
new ColumnAttribute() { StringLength = 20, Position = 2 })
.Property("Tid", typeof(string),
new ColumnAttribute() { StringLength = 20, Position = 4 })
.Property("Address", typeof(string),
new ColumnAttribute() { StringLength = 150, Position = 3 })
.Build();
var dict = new Dictionary<string, object>
{
["Name"] = "张三",
["Address"] = "北京市"
};
var instance = table.CreateInstance(dict);
//根据Type生成表
fsql.CodeFirst.SyncStructure(table.Type);
var insertId = fsql.Insert<object>().AsType(table.Type).AppendData(instance).ExecuteIdentity();
var select = fsql.Select<object>().AsType(table.Type).ToList();
}
}


public class BaseModel
{
[Column(Position = 99)] public DateTime UpdateTime { get; set; }
Expand Down
27 changes: 19 additions & 8 deletions FreeSql/Extensions/DynamicEntityExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public static object CreateInstance(this TableInfo table, Dictionary<string, obj
{
defaultValueInit.Invoke(instance, new object[0]);
}

foreach (var key in table.ColumnsByCs.Keys)
{
if (dict.ContainsKey(key) == false) continue;
Expand Down Expand Up @@ -187,22 +188,32 @@ private void SetTableAttribute(ref TypeBuilder typeBuilder)
if (tableAttribute == null) continue;

var classCtorInfo = tableAttribute.GetType().GetConstructor(Type.EmptyTypes);

var classCtorInfos = tableAttribute.GetType().GetConstructors();
var propertyInfos = tableAttribute.GetType().GetProperties().Where(p => p.CanWrite == true).ToArray();

foreach (var propertyInfo in propertyInfos)
propertyValues.Add(propertyInfo.GetValue(tableAttribute));

//可能存在有参构造
if (classCtorInfo == null)
//是否存在有参构造函数
var existConstructorArguments = classCtorInfos.Any(c => c.GetParameters().Length > 0);
if (existConstructorArguments)
{
var constructorTypes = propertyInfos.Select(p => p.PropertyType);
classCtorInfo = tableAttribute.GetType().GetConstructor(constructorTypes.ToArray());
var customAttributeBuilder = new CustomAttributeBuilder(classCtorInfo, propertyValues.ToArray());
var defaultParamsCtor = classCtorInfos.Where(c => c.GetParameters().Length > 0)
.OrderBy(c => c.GetParameters().Length).First();
//获取参数默认值
var defaultParams = new List<object>();
foreach (var parameterInfo in defaultParamsCtor.GetParameters())
{
defaultParams.Add(parameterInfo.ParameterType.CreateInstanceGetDefaultValue());
}

//思路:先通过构造函数的默认值实例化对象,然后通过属性的方式赋值
var customAttributeBuilder = new CustomAttributeBuilder(defaultParamsCtor, defaultParams.ToArray(),
propertyInfos,
propertyValues.ToArray());
typeBuilder.SetCustomAttribute(customAttributeBuilder);
}
else
{
//不存在构造函数赋值直接属性赋值
var customAttributeBuilder = new CustomAttributeBuilder(classCtorInfo, new object[0], propertyInfos,
propertyValues.ToArray());
typeBuilder.SetCustomAttribute(customAttributeBuilder);
Expand Down

0 comments on commit 2164493

Please sign in to comment.