gpt4 book ai didi

c# - 如何创建一个属性名称动态确定的匿名对象?

转载 作者:可可西里 更新时间:2023-11-01 03:08:43 26 4
gpt4 key购买 nike

给定一个值数组,我想创建一个具有基于这些值的属性的匿名对象。属性名称很简单 "pN"其中 N是数组中值的索引。

例如给定

object[] values = { 123, "foo" };

我想创建匿名对象

new { p0 = 123, p1 = "foo" };

我能想到的唯一方法是使用 switchif链接到合理数量的参数来支持,但我想知道是否有更优雅的方法来做到这一点:

object[] parameterValues = new object[] { 123, "foo" };
dynamic values = null;

switch (parameterValues.Length)
{
case 1:
values = new { p0 = parameterValues[0] };
break;
case 2:
values = new { p0 = parameterValues[0], p1 = parameterValues[1] };
break;
// etc. up to a reasonable # of parameters
}

背景

我有一组现有的方法可以对数据库执行 sql 语句。这些方法通常采用 string对于 sql 语句和 params object[]对于参数,如果有的话。理解是,如果查询使用参数,它们将被命名为@p0, @p1, @p2, etc.。 .

例子:

public int ExecuteNonQuery(string commandText, CommandType commandType, params object[] parameterValues) { .... }

这样调用:

db.ExecuteNonQuery("insert into MyTable(Col1, Col2) values (@p0, @p1)", CommandType.Text, 123, "foo");

现在我想使用 Dapper在此类中包装和公开 Dapper 的 Query<T>方法,并以与现有方法一致的方式进行,例如像这样的东西:

public IEnumerable<T> ExecuteQuery<T>(string commandText, CommandType commandType, params object[] parameterValues) { .... }

但是 Dapper 的 Query<T>方法采用匿名对象中的参数值:

var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid }); 

导致我提出关于创建匿名对象以将参数传递给 Dapper 的问题。


使用 DynamicParameter 添加代码按照@Paolo Tedesco 的要求上课。

string sql = "select * from Account where Id = @p0 and username = @p1";
dynamic values = new DynamicParameter(123, "test");
var accounts = SqlMapper.Query<Account>(connection, sql, values);

在 Dapper 的 SqlMapper.cs 文件的第 581 行抛出异常:

using (var reader = cmd.ExecuteReader())

异常(exception)是 SqlException :

Must declare the scalar variable "@p0".

并检查 cmd.Parameters属性显示没有为命令配置参数。

最佳答案

你在滥用 Dapper,你永远不需要这样做,而是实现 IDynamicParameters 或使用特定的极其灵活的 DynamicParameters 类。

特别是:

string sql = "select * from Account where Id = @id and username = @name";
var values = new DynamicParameters();
values.Add("id", 1);
values.Add("name", "bob");
var accounts = SqlMapper.Query<Account>(connection, sql, values);

DynamicParameters 可以在构造函数中接受匿名类。您可以使用 AddDynamicParams 方法连接 DynamicParameters

此外,对匿名类型没有严格的依赖性。 Dapper 将允许具体类型作为参数,例如:

class Stuff
{
public int Thing { get; set; }
}

...

cnn.Execute("select @Thing", new Stuff{Thing = 1});

凯文有一个类似的问题:Looking for a fast and easy way to coalesce all properties on a POCO - DynamicParameters 在这里也能完美运行,无需任何魔术跳圈。

关于c# - 如何创建一个属性名称动态确定的匿名对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8491849/

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