我如何将 propertyInfo.PropertyType 作为数据类型传递以实例化变量并将其传递给通用函数?
How could I pass a propertyInfo.PropertyType as an Datatype to instanciate a variable and pass it to a generic function?
我正在尝试使用 Dapper 和存储过程编写一些更通用的代码。我做了一些研究,但我卡在了这部分..
我有一些 class 实体,它们的行为类似于将由某些存储过程 return 编辑的实体(无法修改这些过程)。
比如我有这两个classes:
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
}
public class Role
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
存储过程通常return一些select子句,对于这个例子它return两个select子句,每个子句用于用户和角色的信息,所以我有以下 class 用于存储那些..
public class UserAndRoleInfo
{
public IEnumerable<User> users { get; set; }
public IEnumerable<Role> roles { get; set;}
}
在这个项目中,我们必须使用 Dapper,所以我正在做一个通用函数,其中 T 是将 returned 的 class,这个 class 具有相同的结构如上所示,可以有两个或多个实体作为属性。
主要思想是获取 T 的属性,然后对于每个 属性 获取由 select 子句转换为 属性 类型的值 return,最后将此 属性 添加到 class 实例,该实例将被 returned.
public async Task<T> ExecuteStoredProcedureMultiQuery<T>(string cnx, string storedProcedure, object param = null) where T : class, new()
{
using (var conn = new SqlConnection(cnx))
{
conn.Open();
var result = param == null
? await conn.QueryMultipleAsync(
storedProcedure,
commandType: CommandType.StoredProcedure
).ConfigureAwait(false)
: await conn.QueryMultipleAsync(
storedProcedure,
param: param,
commandType: CommandType.StoredProcedure
).ConfigureAwait(false);
T res = new T();
Type t = typeof(T);
PropertyInfo[] propInfos = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach(PropertyInfo propInfo in propInfos)
{
// I want to do something like this
propInfo.PropertyType propValue = result.Read<propInfo.PropertyType.GetEnumUnderlyingType()>();
propInfo.SetValue(res, propValue);
}
conn.Close();
conn.Dispose();
return res;
}
}
这里的问题是我不确定如何得到这个
propInfo.PropertyType propValue = result.Read<propInfo.PropertyType.GetEnumUnderlyingType()>();
我正在研究 Activator.CreateInstance(propInfo.PropertyType)
,但我不确定在这种情况下如何实施它。
如果有什么不清楚或需要更多信息,我会在这里回答。提前致谢。
使用答案 here 作为参考,您可以这样做:
foreach (var propInfo in propInfos)
{
var method = result.GetType().GetMethod(nameof(result.Read));
var generic = method.MakeGenericMethod(propInfo.PropertyType.GetEnumUnderlyingType());
var propValue = generic.Invoke(result, null);
propInfo.SetValue(res, propValue);
}
我正在尝试使用 Dapper 和存储过程编写一些更通用的代码。我做了一些研究,但我卡在了这部分..
我有一些 class 实体,它们的行为类似于将由某些存储过程 return 编辑的实体(无法修改这些过程)。
比如我有这两个classes:
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
}
public class Role
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
存储过程通常return一些select子句,对于这个例子它return两个select子句,每个子句用于用户和角色的信息,所以我有以下 class 用于存储那些..
public class UserAndRoleInfo
{
public IEnumerable<User> users { get; set; }
public IEnumerable<Role> roles { get; set;}
}
在这个项目中,我们必须使用 Dapper,所以我正在做一个通用函数,其中 T 是将 returned 的 class,这个 class 具有相同的结构如上所示,可以有两个或多个实体作为属性。
主要思想是获取 T 的属性,然后对于每个 属性 获取由 select 子句转换为 属性 类型的值 return,最后将此 属性 添加到 class 实例,该实例将被 returned.
public async Task<T> ExecuteStoredProcedureMultiQuery<T>(string cnx, string storedProcedure, object param = null) where T : class, new()
{
using (var conn = new SqlConnection(cnx))
{
conn.Open();
var result = param == null
? await conn.QueryMultipleAsync(
storedProcedure,
commandType: CommandType.StoredProcedure
).ConfigureAwait(false)
: await conn.QueryMultipleAsync(
storedProcedure,
param: param,
commandType: CommandType.StoredProcedure
).ConfigureAwait(false);
T res = new T();
Type t = typeof(T);
PropertyInfo[] propInfos = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach(PropertyInfo propInfo in propInfos)
{
// I want to do something like this
propInfo.PropertyType propValue = result.Read<propInfo.PropertyType.GetEnumUnderlyingType()>();
propInfo.SetValue(res, propValue);
}
conn.Close();
conn.Dispose();
return res;
}
}
这里的问题是我不确定如何得到这个
propInfo.PropertyType propValue = result.Read<propInfo.PropertyType.GetEnumUnderlyingType()>();
我正在研究 Activator.CreateInstance(propInfo.PropertyType)
,但我不确定在这种情况下如何实施它。
如果有什么不清楚或需要更多信息,我会在这里回答。提前致谢。
使用答案 here 作为参考,您可以这样做:
foreach (var propInfo in propInfos)
{
var method = result.GetType().GetMethod(nameof(result.Read));
var generic = method.MakeGenericMethod(propInfo.PropertyType.GetEnumUnderlyingType());
var propValue = generic.Invoke(result, null);
propInfo.SetValue(res, propValue);
}