Orm { 课程尝试=课程; courseEntry.Locations=courseEntry.Locations??新列表(); 添加(courseEntry.Id,courseEntry); } courseEntry.Locations.Add(位置); 复课; }, 斯普利顿:“Id”) .Distinct() .ToList(); 退货清单; }

Orm { 课程尝试=课程; courseEntry.Locations=courseEntry.Locations??新列表(); 添加(courseEntry.Id,courseEntry); } courseEntry.Locations.Add(位置); 复课; }, 斯普利顿:“Id”) .Distinct() .ToList(); 退货清单; },orm,dapper,Orm,Dapper,还有另一种使用JSON结果的方法。尽管已被接受的答案和其他答案都得到了很好的解释,但我只是想到了另一种方法来获得结果 创建存储过程或select qry以json格式返回结果。然后将结果对象反序列化为所需的类格式。请通读示例代码 using (var db = connection.OpenConnection()) { var results = await db.QueryAsync("your_sp_name",..); var

还有另一种使用JSON结果的方法。尽管已被接受的答案和其他答案都得到了很好的解释,但我只是想到了另一种方法来获得结果

创建存储过程或select qry以json格式返回结果。然后将结果对象反序列化为所需的类格式。请通读示例代码

using (var db = connection.OpenConnection())
{                
  var results = await db.QueryAsync("your_sp_name",..);
  var result = results.FirstOrDefault();    
                    
  string Json = result?.your_result_json_row;
                   
  if (!string.IsNullOrEmpty(Json))
  {
     List<Course> Courses= JsonConvert.DeserializeObject<List<Course>>(Json);
  }
    
  //map to your custom class and dto then return the result        
}
使用(var db=connection.OpenConnection())
{                
var results=await db.QueryAsync(“您的sp名称,…);
var result=results.FirstOrDefault();
字符串Json=result?。您的\u result\u Json\u行;
如果(!string.IsNullOrEmpty(Json))
{
List Courses=JsonConvert.DeserializeObject(Json);
}
//映射到自定义类和dto,然后返回结果
}

这是另一个思考过程。请查看相同的内容。

谢谢Sam的澄清。正如您前面所述,我正在运行第二个查询,获取位置并手动将其分配给课程。我只是想确保我没有错过一些可以通过一个查询来实现的功能。Sam,在一个大型应用程序中,集合定期暴露在域对象上,如示例中所示,您建议将此代码物理定位在何处?(假设您希望使用来自代码中许多不同位置的类似完全构造的[Course]实体)在构造函数中?在一流工厂?其他地方?相关问题:这是我的解决方案:这节省了我很多时间。其他人可能需要的一个修改是包含splitOn:参数,因为我没有使用默认的“Id”。对于LEFT JOIN,您将在位置列表中获得一个null项。通过var items=lookup.Values删除它们;items.ForEach(x=>x.Locations.RemoveAll(y=>y==null));除非在第1行末尾有一个分号并删除“AsQueryable()”之前的逗号,否则无法编译此文件。我会编辑答案,但在我之前的62位选民似乎认为没关系,也许我遗漏了一些东西……对于左派加入来说:不需要再做一次讨论。添加它之前只需检查:if(l!=null)course.Locations.Add(l.),因为您使用的是字典。如果您使用QueryMultiple并分别查询课程和位置,然后使用同一词典为课程分配位置,这会更快吗?它本质上是相同的,减去内部连接,这意味着sql不会传输那么多字节?需要注意一点。如果有很多位置/课程,您应该循环浏览这些位置一次,并将它们放入字典查找中,这样您就有了N个logn而不是N^2个speed。在较大的数据集中有很大的不同。唯一的问题是,您将在每个位置记录上复制头。如果每门课程有多个地点,可能会有大量的数据重复通过网络传输,这将增加带宽,需要更长的时间来解析/映射,并使用更多的内存来读取所有这些内容。我不确定这是否如我预期的那样工作。我有1个父对象和3个相关对象。我使用的查询返回三行。描述父级的第一列,为每行复制;id上的拆分将标识每个唯一的子级。我的结果是有3个孩子的3个重复父母。。。。应该是有3个孩子的单亲。@topwik是对的。这对我来说也不起作用。实际上我有三个父母,每个人有一个孩子。不确定为什么我的结果与@topwik不同,但它仍然不起作用。这个答案是错误的,因为返回数据库中的一个课程和三个位置,将返回三个课程,每个课程和一个位置。
var courses = cnn.Query<Course>("select * from Courses where Category = 1 Order by CreationDate");
var mappings = cnn.Query<CourseLocation>(
   "select * from CourseLocations where CourseId in @Ids", 
    new {Ids = courses.Select(c => c.Id).Distinct()});
var locations = cnn.Query<Location>(
   "select * from Locations where Id in @Ids",
   new {Ids = mappings.Select(m => m.LocationId).Distinct()}
);
var lookup = new Dictionary<int, Course>();
conn.Query<Course, Location, Course>(@"
    SELECT c.*, l.*
    FROM Course c
    INNER JOIN Location l ON c.LocationId = l.Id                    
    ", (c, l) => {
        Course course;
        if (!lookup.TryGetValue(c.Id, out course))
            lookup.Add(c.Id, course = c);
        if (course.Locations == null) 
            course.Locations = new List<Location>();
        course.Locations.Add(l); /* Add locations to course */
        return course;
     }).AsQueryable();
var resultList = lookup.Values;
var lookup = new Dictionary<int, Course>()
conn.Query<Course, Location, Course>(@"
    SELECT c.*, l.Name, l.otherField, l.secondField
    FROM Course c
    INNER JOIN Location l ON c.LocationId = l.Id                    
    ", (c, l) => {
        Course course;
        if (!lookup.TryGetValue(c.Id, out course)) {
            lookup.Add(c.Id, course = c);
        }
        if (course.Locations == null) 
            course.Locations = new List<Location>();
        course.Locations.Add(a);
        return course;
     },
     ).AsQueryable();
var resultList = lookup.Values;
var results = cnn.QueryMultiple(@"
    SELECT * 
      FROM Courses 
     WHERE Category = 1 
  ORDER BY CreationDate
          ; 
    SELECT A.*
          ,B.CourseId 
      FROM Locations A 
INNER JOIN CourseLocations B 
        ON A.LocationId = B.LocationId 
INNER JOIN Course C 
        ON B.CourseId = B.CourseId 
       AND C.Category = 1
");

var courses = results.Read<Course>();
var locations = results.Read<Location>(); //(Location will have that extra CourseId on it for the next part)
foreach (var course in courses) {
   course.Locations = locations.Where(a => a.CourseId == course.CourseId).ToList();
}
var lookup = new Dictionary<int, dynamic>();
conn.Query<dynamic, dynamic, dynamic>(@"
    SELECT A.*, B.*
    FROM Client A
    INNER JOIN Instance B ON A.ClientID = B.ClientID                
    ", (A, B) => {
        // If dict has no key, allocate new obj
        // with another level of array
        if (!lookup.ContainsKey(A.ClientID)) {
            lookup[A.ClientID] = new {
                ClientID = A.ClientID,
                ClientName = A.Name,                                        
                Instances = new List<dynamic>()
            };
        }

        // Add each instance                                
        lookup[A.ClientID].Instances.Add(new {
            InstanceName = B.Name,
            BaseURL = B.BaseURL,
            WebAppPath = B.WebAppPath
        });

        return lookup[A.ClientID];
    }, splitOn: "ClientID,InstanceID").AsQueryable();

var resultList = lookup.Values;
return resultList;
var coursesWithLocations = 
    conn.Query<Course, Location, Course>(@"
        SELECT c.*, l.*
        FROM Course c
        INNER JOIN Location l ON c.LocationId = l.Id                    
        ", (course, location) => {
            course.Locations = course.Locations ?? new List<Location>();
            course.Locations.Add(location); 
            return course;
        }).AsQueryable();
string query = @"SELECT c.*, l.*
    FROM Course c
    INNER JOIN Location l ON c.LocationId = l.Id";
using (SqlConnection conn = DB.getConnection())
{
    conn.Open();
    var courseDictionary = new Dictionary<Guid, Course>();
    var list = conn.Query<Course, Location, Course>(
        query,
        (course, location) =>
        {
            if (!courseDictionary.TryGetValue(course.Id, out Course courseEntry))
            {
                courseEntry = course;
                courseEntry.Locations = courseEntry.Locations ?? new List<Location>();
                courseDictionary.Add(courseEntry.Id, courseEntry);
            }

            courseEntry.Locations.Add(location);
            return courseEntry;
        },
        splitOn: "Id")
    .Distinct()
    .ToList();

    return list;
}
using (var db = connection.OpenConnection())
{                
  var results = await db.QueryAsync("your_sp_name",..);
  var result = results.FirstOrDefault();    
                    
  string Json = result?.your_result_json_row;
                   
  if (!string.IsNullOrEmpty(Json))
  {
     List<Course> Courses= JsonConvert.DeserializeObject<List<Course>>(Json);
  }
    
  //map to your custom class and dto then return the result        
}