使用Dapper在Linq中进行多对多 [英] Many to Many in Linq using Dapper

查看:89
本文介绍了使用Dapper在Linq中进行多对多的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有地方,每个地方可以有很多标签.每个标签都可以分配到很多地方.

I have Places, each place can have many tags. Each tag can be assigned to many places.

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; }
}

数据库中有相应的带有外键的表.

The database has equivalent tables with foreign keys as appropriate.

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

I want to get a collection of Places, and I want each Place to have an appropriate colleciton of Tags. I guess using Linq might be required.

我已经找到了很多关于此的文章,但是它们并不是完全相同/只处理一个int列表,而不是两个对象集合.

I've found various articles on this, but they aren't quite the same / deal with a list of ints rather than two collections of objects.

例如

LINQ收集条款中的位置

做到这一点的最好方法是什么?

What's the best way of doing this?

推荐答案

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

The classical approach with Dapper is to use a Dictionary to store the main objects while the query enumerates the records

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;
}

这篇关于使用Dapper在Linq中进行多对多的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆