【问题标题】:Using Dapper to map more than 5 types使用 Dapper 映射超过 5 种类型
【发布时间】:2018-07-24 02:52:51
【问题描述】:

我目前正在构建一个将 12 个表连接在一起的 SELECT 查询。我一直在使用 Dapper 进行所有其他查询,并且效果很好。问题是,泛型方法只有五个泛型参数。

我之前已经修改了代码以支持最多 6 个用于另一个查询,但现在我真的认为我不应该再破解 6 个级别的泛型。

有没有办法向 dapper 传递一个类型数组,并将结果作为一个对象数组返回,如果需要我可以手动转换?

我也可能以错误的方式解决问题!任何帮助将不胜感激!

【问题讨论】:

    标签: c# sql dapper


    【解决方案1】:

    在我从事的一个项目中,我看到类似这样的东西可以映射超过 7 种类型。我们使用 Dapper 1.38:

    connection.Query<TypeOfYourResult>
    (
       queryString,
       new[]
       {
          typeof(TypeOfArgument1),
          typeof(TypeOfArgument2),
          ...,
          typeof(TypeOfArgumentN)
       },
       objects =>
       {
          TypeOfArgument1 arg1 = objects[0] as TypeOfArgument1;
          TypeOfArgument2 arg2 = objects[1] as TypeOfArgument2;
          ...
          TypeOfArgumentN argN = objects[N] as TypeOfArgumentN;
    
         // do your processing here, e.g. arg1.SomeField = arg2, etc.
         // also initialize your result
    
         var result = new TypeOfYourResult(...)
    
         return result;
       },
       parameters,
       splitOn: "arg1_ID,arg2_ID, ... ,argN_ID"
    );
    

    queryString 是不言自明的。 splitOn 参数说明 Dapper 应该如何从 SELECT 语句中拆分列,以便所有内容都可以正确映射到对象, you can read about it here.

    【讨论】:

    • 将此标记为答案,因为它是最新的! 3 年前,这在我的用例中可以完美运行! (时间过得真快!)
    • 很高兴得到这个答案!
    • 哈利路亚! :D 谢谢@Radek 先生
    • 提供的链接已失效。
    • 此链接应该与原始答案所指的内容接近:tritac.com/blog/dappernet-by-example
    【解决方案2】:

    您可以使用动态查询并在之后对其进行映射。像这样的

    var result = conn.Query<dynamic>(query).Select(x => new Tuple<Type1, Type2, Type3, Type4, Type5>( 
    // type initialization here 
        new Type1(x.Property1,x.Property2),
        new Type2(x.Property3,x.Property4),
        new Type3(x.Property5,x.Property6) etc....));
    

    编辑:对于相当大的结果集,另一种选择可能是使用多个查询,然后使用网格阅读器。这可能对你有用。

    这是从精巧时代采取的例子:

    var sql = 
    @"
    select * from Customers where CustomerId = @id
    select * from Orders where CustomerId = @id
    select * from Returns where CustomerId = @id";
    
    using (var multi = connection.QueryMultiple(sql, new {id=selectedId}))
    {
       var customer = multi.Read<Customer>().Single();
       var orders = multi.Read<Order>().ToList();
       var returns = multi.Read<Return>().ToList();
       ...
    } 
    

    【讨论】:

    • 我已经考虑过了。但我有大约 87 列要映射。我的查询完美地映射到我的对象。我最后的手段是手动地图,但除此之外,我非常不想输入所有列:P
    • 我明白了,您可能想看看 Grid Reader 选项 - 请参阅我的编辑 :)
    • 不想在一个人做到这一点时运行大量查询。但是感谢您的帮助:)
    • 如果性能损失不是问题,我会选择最实用的东西。映射 87 列肯定不是:P
    • 我最终修改了 Dapper.cs,使其拥有多达 12 种类型的泛型。不是太难,但很痛苦。我将@Alex 的帖子标记为答案,因为它基本上回答了我的问题。
    【解决方案3】:

    很久以前就已经回答了,但我想在这里加两分钱。与其手动修改 Dapper 的源代码,不如直接用这些字段创建一个 poco 类,然后像使用表格一样使用查询?

    映射可以正常工作,我知道进行该类定义也很痛苦,但似乎比处理 Dapper 以后的更新更容易。

    【讨论】:

    • 这段代码现在已经完全失效了(并且开源了:bitbucket.org/cdroulers/invup)。但我以后可能会将它用于另一个项目。感谢您的回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    相关资源
    最近更新 更多