Dapper 如何在没有 setter 的情况下设置属性
How Dapper sets properties without setters
我有一个模型:
public class Model
{
public int Id { get;}
public string Name { get; }
public string AnotherName { get; }
}
默认构造函数,没有setters,所以我们在IL.class生成的class中没有publicsetter方法。
但是 Dapper
以某种方式初始化我的数据。所有属性都已填充。
var sql = $@"SELECT id as Id, name as Name, another_name as AnotherName FROM dapper";
var raws = (connection.QueryAsync<Model>(sql).Result).AsList();
我找到了源代码,它们通过 Setter 方法设置,但是当我尝试像 Dapper
那样获取 setter 时,我得到了 null methodInfo。这是一些 Dapper
源代码 SqlMapper:3320
if (specializedConstructor == null)
{
// Store the value in the property/field
if (item.Property != null)
{
il.Emit(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, DefaultTypeMap.GetPropertySetter(item.Property, type));
}
else
{
il.Emit(OpCodes.Stfld, item.Field); // stack is now [target]
}
}
和 DefaultTypeMap.GetPropertySetter
:
internal static MethodInfo GetPropertySetter(PropertyInfo propertyInfo, Type type)
{
if (propertyInfo.DeclaringType == type) return propertyInfo.GetSetMethod(true);
return propertyInfo.DeclaringType.GetProperty(
propertyInfo.Name,
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
Type.DefaultBinder,
propertyInfo.PropertyType,
propertyInfo.GetIndexParameters().Select(p => p.ParameterType).ToArray(),
null).GetSetMethod(true);
}
你可以写示例,我也是,你会看到如果你的 属性 没有任何 setter,那么 setter 方法信息将为空。
https://github.com/StackExchange/Dapper/blob/main/Dapper/SqlMapper.cs#L3312-L3323
它在内部 Dapper 模型中存储 属性,如果 属性 没有 属性 - 它通过支持字段设置它。
我有一个模型:
public class Model
{
public int Id { get;}
public string Name { get; }
public string AnotherName { get; }
}
默认构造函数,没有setters,所以我们在IL.class生成的class中没有publicsetter方法。
但是 Dapper
以某种方式初始化我的数据。所有属性都已填充。
var sql = $@"SELECT id as Id, name as Name, another_name as AnotherName FROM dapper";
var raws = (connection.QueryAsync<Model>(sql).Result).AsList();
我找到了源代码,它们通过 Setter 方法设置,但是当我尝试像 Dapper
那样获取 setter 时,我得到了 null methodInfo。这是一些 Dapper
源代码 SqlMapper:3320
if (specializedConstructor == null)
{
// Store the value in the property/field
if (item.Property != null)
{
il.Emit(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, DefaultTypeMap.GetPropertySetter(item.Property, type));
}
else
{
il.Emit(OpCodes.Stfld, item.Field); // stack is now [target]
}
}
和 DefaultTypeMap.GetPropertySetter
:
internal static MethodInfo GetPropertySetter(PropertyInfo propertyInfo, Type type)
{
if (propertyInfo.DeclaringType == type) return propertyInfo.GetSetMethod(true);
return propertyInfo.DeclaringType.GetProperty(
propertyInfo.Name,
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
Type.DefaultBinder,
propertyInfo.PropertyType,
propertyInfo.GetIndexParameters().Select(p => p.ParameterType).ToArray(),
null).GetSetMethod(true);
}
你可以写示例,我也是,你会看到如果你的 属性 没有任何 setter,那么 setter 方法信息将为空。
https://github.com/StackExchange/Dapper/blob/main/Dapper/SqlMapper.cs#L3312-L3323
它在内部 Dapper 模型中存储 属性,如果 属性 没有 属性 - 它通过支持字段设置它。