【问题标题】:Mapping Dapper Query to a Collection of Objects (which itself has a couple of Collections)将 Dapper 查询映射到对象集合(它本身有几个集合)
【发布时间】:2012-05-09 11:16:37
【问题描述】:

我想执行单个查询(或具有多个结果集的存储过程)。我知道如何使用 Dapper 进行多重映射,但我无法排序如何将两个集合映射到同一个父级。基本上,给定这个对象定义......

class ParentObject
{
    string Name { get; set; }
    ICollection<ChildObjectOne> ChildSetOne {get;set;}
    ICollection<ChildObjectTwo> ChildSetTwo { get; set; }
}

class ChildObjectOne
{
    string Name { get; set; }
}

class ChildObjectTwo
{
    int id { get; set; }
    string LocationName { get; set; }
}

我希望能够运行以某种方式产生的 Dapper 查询:

IQueryable<ParentObject> result = cnn.Query(
          // Some really awesome dapper syntax goes here
);

【问题讨论】:

    标签: c# dapper multi-mapping


    【解决方案1】:

    不确定您是否不想使用 MultiMapping,但以下是它适用于您的情况的方法。据我所知并阅读 SO,不可能用简单的Query 映射深层嵌套对象图。

     static void Main(string[] args)
            {
                var sqlParent = "SELECT parentId as Id FROM ParentTable WHERE parentId=1;";
                var sqlChildOneSet = "SELECT Name FROM ChildOneTable;"; // Add an appropriate WHERE
                var sqlChildTwoSet = "SELECT Id, LocationName FROM ChildTwoTable;"; // Add an appropriate WHERE
    
                var conn = GetConnection() // whatever you're getting connections with
                using (conn)
                {
                    conn.Open();
                    using (var multi = conn.QueryMultiple(sqlParent + sqlChildOneSet + sqlChildTwoSet))
                    {
                        var parent = multi.Read<ParentObject>().First();
                        parent.ChildSetOne = multi.Read<ChildOne>().ToList();
                        parent.ChildSetTwo = multi.Read<ChildTwo>().ToList();
                    }
                }
            }
    

    嵌套对象和 dapper 的类似问题:

    https://stackoverflow.com/search?q=nested+objects+%2B+dapper

    【讨论】:

      【解决方案2】:

      在这种情况下,可以使用IEnumerable&lt;TReturn&gt; Query&lt;TFirst, TSecond, TThird, TReturn&gt;(this IDbConnection cnn, string sql, Func&lt;TFirst, TSecond, TThird, TReturn&gt; map); 方法实现具有一对多关系的对象。但是,您需要对实体进行一些更改才能获得足够的信息。

      这里有一些类似问题的 SO 主题。

      How do I map lists of nested objects with Dapper

      Extension function to make it cleaner

      Dapper.Net by example - Mapping Relationships

      public class ParentObject
      {
          public ParentObject()
          {
              ChildSetOne = new List<ChildObjectOne>();
              ChildSetTwo = new List<ChildObjectTwo>();
          }
          // 1) Although its possible to do this without this Id property, For sanity it is advisable.
          public int Id { get; set; }
          public string Name { get; set; }
          public ICollection<ChildObjectOne> ChildSetOne {get; private set;}
          public ICollection<ChildObjectTwo> ChildSetTwo { get; private set; }
      }
      
      public class ChildObjectOne
      {
          // 2a) Need a ParentId
          public int ParentId { get; set; }
          public string Name { get; set; }
      }
      
      public class ChildObjectTwo
      {
          // 2b) This ParentId is not required but again for sanity it is advisable to include it.
          public int ParentId { get; set; }
          public int id { get; set; }
          public string LocationName { get; set; }
      }
      
      public class Repository
      {
          public IEnumerable<ParentObject> Get()
          {
              string sql = 
                  @"SELECT 
                      p.Id, 
                      p.Name, 
                      o.Name, 
                      o.ParentId, 
                      t.Id, 
                      t.LocationName, 
                      t.ParentId 
                  FROM 
                      Parent p 
                          LEFT JOIN ChildOne o on o.ParentId = p.Id 
                          LEFT JOIN ChildTwo t on t.ParentId = p.Id 
                  WHERE 
                      p.Name LIKE '%Something%'";
      
              var lookup = new Dictionary<int, ParentObject>();
              using (var connection = CreateConnection())
              {
      
                  connection.Query<ParentObject, ChildObjectOne, ChildObjectTwo, ParentObject>(
                      sql, (parent, childOne, childTwo) =>
                      {
                          ParentObject activeParent;
      
                          if (!lookup.TryGetValue(childOne.ParentId, out activeParent)) 
                          {
                              activeParent = parent;
                              lookup.add(activeParent.Id, activeParent);
                          }
      
                          //TODO: if you need to check for duplicates or null do so here
                          activeParent.ChildSetOne.Add(childOne);
      
                          //TODO: if you need to check for duplicates or null do so here
                          activeParent.ChildSetTwo.Add(childTwo);
      
                      });   
              }
              return lookup.Values;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-09
        • 2015-07-13
        • 1970-01-01
        相关资源
        最近更新 更多