gpt4 book ai didi

c# - 来自 Type 的 Dapper 强类型集合

转载 作者:行者123 更新时间:2023-11-30 22:21:14 25 4
gpt4 key购买 nike

在我的应用程序中,我使用 Dapper 访问数据库。

我有以下示例代码:

public IEnumerable GetByParentId(Type childType, string table) 
{
IDbConnection _connection = _dbProvider.GetConnection();

var _sqlString = "select * from " + table;

IEnumerable _ret = _connection.Query(_sqlString).ToList();
//return IEnumerable<Dapper.SqlMapper.FastExpando>

return _ret;
}

可以将 FastExpando 项转换为我的 childType 或强制 Dapper 返回强类型集合吗?

我无法更改我的方法签名!

最佳答案

您可以通过反射调用 Query 方法并提供您的 childType 的通用 TItem 参数。然后,Dapper 将返回 IEnumerable,您将能够对其进行转换。此外,您可以 fork Dapper(它不是很大)并进行非常简单的 Query 重载,这将包括(Type childType)参数并在其中调用适当的方法。

您面临的是 C# 在使用泛型时遇到的问题。作为静态类型语言,C# 不适合使用动态类型。如果您想动态地工作,您总会以反射(reflection)告终。

这是一个示例,说明如何使用类型参数调用查询方法。您可能需要更正一下:

    public IEnumerable GetByParentId(Type childType, string table)
{
IDbConnection _connection = _dbProvider.GetConnection();

var _sqlString = "select * from " + table;

var t = typeof(SqlMapper);
var genericQuery = t.GetMethods().Where(x => x.Name == "Query" && x.GetGenericArguments().Length == 1).First(); // You can cache this object.
var concreteQuery = genericQuery.MakeGenericMethod(childType); // you can also keep a dictionary of these, for speed.
var _ret = (IEnumerable)concreteQuery.Invoke(null, new object[] { _connection, _sqlString });

return _ret;
}

追加:

另外,我在这里看到了一个更普遍的设计问题。你想动态指定类型,但又想获得静态类型的对象,你将能够转换(我假设是静态的,或者你想继续反射?)。那么...为什么首先要创建动态界面?你说,你不能改变界面,但这看起来有点愚蠢。看起来,您的所有上下文都是静态类型的,但是由于某种原因,您有一个动态类型的方法。如果您在编译时知道类型(或通过运行时的通用参数),那么您应该简单地将您的方法更改为如下所示:

    public IEnumerable<T> GetByParentId<T>(string table)
{
IDbConnection _connection = _dbProvider.GetConnection();
var _sqlString = "select * from " + table;
var _ret = _connection.Query<T>(_sqlString);
return _ret;
}

关于c# - 来自 Type 的 Dapper 强类型集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14501175/

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