gpt4 book ai didi

c# - Dapper 如何设置只读属性?

转载 作者:行者123 更新时间:2023-12-04 08:35:09 24 4
gpt4 key购买 nike

我注意到以下与 Dapper 和 C# 相关的行为 read-only auto-properties (在 C# 6 中引入)。
Dapper 能够使用只读属性集映射类的实例,根据我对只读属性如何工作的理解,这是不可能的。
以下代码演示了这一点:

using Dapper;
using Npgsql;
using System;
using System.Threading.Tasks;

namespace ConsoleApp1
{
class Model
{
public long Id { get; }
}

class Program
{
static async Task<Model> GetData()
{
using (var connection = new NpgsqlConnection("..."))
{
await connection.OpenAsync();

var sql = @"
SELECT 22 AS Id";

return await connection.QuerySingleAsync<Model>(sql);
}
}

static async Task Main(string[] args)
{
var model = await GetData();
Console.WriteLine(model.Id);

var model2 = new Model();
//model2.Id = 22;

var model3 = new Model
{
//Id = 22;
};
}
}
}
注释掉的行产生编译时错误 CS0200正如预期的那样。
不需要数据库设置,只需要一个有效的 SQL 连接(我使用的是 Postgres)。从 GetData 返回的模型设置了它的 Id 属性,如果我尝试手动创建 Model 类的实例,我无法设置它的 Id 属性,因为它是只读的。
我想知道 Dapper 如何设置属性?我尝试遵循 Dapper 存储库中的代码,但它超出了我的理解水平。
我设法跟进 SqlMapper.cs#L1530这就是我认为魔法正在发生的地方,但除此之外,它太难理解了。
如果有人能用简单的术语解释,我将不胜感激:)
谢谢你。

最佳答案

在幕后,您的声明:

public long Id { get; }
实际上编译为以下 C# 代码:
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly long <Id>k__BackingField;

public long Id
{
[CompilerGenerated]
get
{
return <Id>k__BackingField;
}
}
Reflection ,你可以做一些非常疯狂的事情。其中之一是设置标记为 readonly 的字段的值。 . (这有一些有趣的含义,比如能够将 string.Empty 设置为任何你想要的!)
在 Dapper 的情况下,它有效地执行以下操作,但进行了更多错误检查:
Model m = <instance of your Model class>;
Type t = m.GetType();
string propertyName = "Id"; // read using Reflection
FieldInfo fi = t.GetField("<" + propertyName + ">k__BackingField",
BindingFlags.Instance | BindingFlags.NonPublic);
if (fi != null)
fi.SetValue(m, 22); // 22 = value read from DB

关于c# - Dapper 如何设置只读属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64836764/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com