如何将 Dapper 动态返回类型转换为具体类

问题描述 投票:0回答:2

我有一个异步方法,它使用 dapper 返回动态类型,但在调用方法中我想要一个具体的类。例如...

public async Task<dynamic> MyDapperMethod(string sql)
{
    var result = await conn.QueryFirstOrDefaultAsync(sql);
    return result;
}

然后在调用方法中...

public async Task<Customer> GetCustomer(int id)
{
    Customer cust = new Customer();

    var qry = await MyDapperMethod($"SELECT * FROM Customers WHERE Id = {id}");
    cust = (Customer)qry;

    return cust;
}

我收到无效的转换错误。它无法将“DapperRow”强制转换为“Customer”。 有什么办法可以解决这个问题吗?

一些建议是手动将 DapperRow 中的每个字段移动到具体类中相应的属性。但还有更好的办法吗?

c# dynamic dapper
2个回答
0
投票

改用 QueryFirstOrDefaultAsync<>()。

public async Task<Customer> MyDapperMethod(string sql)
{
    var result = await conn.QueryFirstOrDefaultAsync<Customer>(sql);
    return result;
}

0
投票

最好的答案是“不要使用

dynamic
。但是,我意识到有时您最终不得不使用一些库代码。如果您不打算使用动态,您可以将您的
MyDapperMethod
更改为类似于@sarmad建议的内容,例如:

public async Task<T> MyDapperMethod(string sql)
{
    var result = await conn.QueryFirstOrDefaultAsync<T>(sql);
    return result;
}

您可以将其称为传递您的

Customer
类型。

但是,您会注意到该方法仅抽象您的连接处理。否则,它看起来非常像原始的 Dapper 调用。

一些代码审查
当我们这样做时,您可能以错误的方式进行连接处理。

SqlConnection
类型(与大多数
IDbConnection
实现一样)期望消费者为每个工作单元创建一个新连接,然后快速处置该新连接 - 它会在幕后为您进行池化。

因此,如果您已习惯使用

dynamic
,这里有两种可能的解决方案:

1。使用带有

dynamic
参数

的构造函数

Customer
类中创建一个构造函数,如下所示:

public Customer (dynamic customerRecord){
    Name = customerRecord.Name;
    Address = customerRecord.Address;
    PhoneNumber = customerRecord.PhoneNumber;
    // etc.
}

有了这个,你的

GetCustomer
最终看起来像:

public async Task<Customer> GetCustomer(int id)
{
    var result = await MyDapperMethod($"SELECT * FROM Customers WHERE Id = {id}");
    return new Customer (result);
}

更多代码审查
声明

cust
变量时,无需对其进行初始化。通过在代码中执行的操作,您不必要地运行了默认的
Customer
构造函数,并且创建了需要清理的垃圾。另外,不要使用 SQL 查询进行字符串连接或插值(查找“SQL 注入”和“Little Bobby 表”)。您的代码应如下所示:

public async Task<Customer> GetCustomer(int id)
{
    var result = await MyDapperMethod($"SELECT * FROM Customers WHERE Id = @Id", new {Id = id});
    return new Customer (result);
}

我现在要发布这个。基于反射的解决方案涉及更多 - 我需要完成一些工作。我稍后应该可以更新。

© www.soinside.com 2019 - 2024. All rights reserved.