c# - 使用 Dapper 在 Linq 中进行多对多

标签 c# linq dapper

我有地点,每个地点可以有很多标签。每个标签可以分配到许多地方。

public class Place {
    public int Id { get; set; }
    public string PlaceName { get; set; }

    public IEnumerable<Tag> Tags { get; set; }
}

public class Tag {
    public int Id { get; set; }
    public string TagName { get; set; }
}

public class TagPlace {
    public int Id { get; set; }
    public PlaceId { get; set; }
    public TagId { get; set; }
}

数据库具有相应的带有外键的等效表。

我想要获取地点集合,并且希望每个地点都有适当的标签集合。我想可能需要使用 Linq。

我找到了有关此问题的各种文章,但它们并不完全相同/处理整数列表而不是两个对象集合。

例如 https://social.msdn.microsoft.com/Forums/en-US/fda19d75-b2ac-4fb1-801b-4402d4bd5255/how-to-do-in-linq-quotselect-from-employee-where-id-in-101112quot?forum=linqprojectgeneral

LINQ Where in collection clause

最好的方法是什么?

最佳答案

Dapper 的经典方法是使用字典来存储主要对象,而查询则枚举记录

public  IEnumerable<Place> SelectPlaces()
{
    string query = @"SELECT p.id, p.PlaceName, t.id, t.tagname
                     FROM Place p INNER JOIN TagPlace tp ON tp.PlaceId = p.Id
                     INNER JOIN Tag t ON tp.TagId = t.Id";
    var result = default(IEnumerable<Place>);
    Dictionary<int, Place> lookup = new Dictionary<int, Place>();
    using (IDbConnection connection = GetOpenedConnection())
    {
         // Each record is passed to the delegate where p is an instance of
         // Place and t is an instance of Tag, delegate should return the Place instance.
         result = connection.Query<Place, Tag, Place(query, (p, t) =>
         {
              // Check if we have already stored the Place in the dictionary
              if (!lookup.TryGetValue(p.Id, out Place placeFound))
              {
                   // The dictionary doesnt have that Place 
                   // Add it to the dictionary and 
                   // set the variable where we will add the Tag
                   lookup.Add(p.Id, p);
                   placeFound = p;
                   // Probably it is better to initialize the IEnumerable
                   // directly in the class 
                   placeFound.Tags = new List<Tag>();
              }

              // Add the tag to the current Place.
              placeFound.Tags.Add(t);
              return placeFound;

          }, splitOn: "id");
          // SplitOn is where we tell Dapper how to split the record returned
          // in the two instances required, but here SplitOn 
          // is not really needed because "Id" is the default.

     }
     return result;
}

关于c# - 使用 Dapper 在 Linq 中进行多对多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50786514/

相关文章:

c# - 如何将其他文件添加到 Visual Studio 2017 中的 NuGet 包?

c# - 在基本 Azure Function 项目中找不到 ServiceBusTrigger

c# - 使用 Linq to C# 获取特定属性值

c# - 如何使用 Colllection.ToDictionary() 将 Dictionary<dynamic, dynamic> 转换为 Dictionary<string, string>

orm - 如何使用 Dapper 映射嵌套对象列表

c# - 如何获取窗体的内部宽度和高度

c# - 在 LINQ 中合并记录

c# - 如何将 IList<T> 映射到位图?

orm - 小巧玲珑填充 DropDownlist

c# - 如何告诉 Range.NumberFormat 按原样放置数据?