Dapper 如何在没有 setter 的情况下设置属性

Posted

技术标签:

【中文标题】Dapper 如何在没有 setter 的情况下设置属性【英文标题】:How Dapper sets properties without setters 【发布时间】:2020-06-12 12:43:23 【问题描述】:

我有一个模型:

    public class Model
    
        public int Id  get;

        public string Name  get; 

        public string AnotherName  get; 
    

默认构造函数,没有setter,所以我们在IL生成的类中没有公共的setter方法。

但是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方法信息将为null。

【问题讨论】:

【参考方案1】:

https://github.com/StackExchange/Dapper/blob/main/Dapper/SqlMapper.cs#L3312-L3323

它将属性存储在内部 Dapper 模型中,如果该属性没有属性 - 它通过支持字段设置它。

【讨论】:

“如果该属性没有属性”?你的意思是“如果属性没有setter”?

以上是关于Dapper 如何在没有 setter 的情况下设置属性的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Dapper 在有/没有迷你分析器连接的情况下为 Postgres 生成不同的 SQL

Dapper多表查询时子表字段为空

在没有 Setter 的情况下设置实例的属性 [重复]

如何在不明确指定主键的情况下使用 Dapper Extensions 将对象插入 PostGreSql?

如何在 Dapper.NET 中使用事务?

如何让 Dapper 动态不区分大小写?