Dapper One-To-Many,有多个表格

时间:2018-06-11 22:37:19

标签: .net dapper

我让Dapper检索我的数据:

IDM

它应该返回一个商品列表,每个商品都包含一个OfferDetails列表和一个SomeLookup。

我得到的是每个OrderDetails对象的订单列表。它返回连接的数据集并为每条记录填充一个Order(并且每个记录中都有1个OrderDetails项)。

在重复检测中我做错了什么?

2 个答案:

答案 0 :(得分:3)

我假设 OfferDetails / OfferBets 还包含一个名为 Id 的列,添加到 OfferId ,此列放在 OfferId <之前/ em>这就搞砸了。因此,如果您将 splitOn 参数更改为 splitOn:“Id,SomeLookupId”它可能会有效。

[Test]
public void tstAbc()
{
    using (var dbConnection = new SqlConnection(_connectionString))
    {
        const string sql = @"WITH Offers AS (

                                 SELECT * FROM (
                                     VALUES (1, 1), (2, 1), (3, 2)
                                     ) AS a (Id, SomeLookupId)
                             ),

                             OfferBets AS (

                                 SELECT * FROM (
                                     VALUES
                                         (1, 1), (2, 1), (3, 2), (4, 3)
                                     ) AS a (Id, OfferId)

                             ),

                             SomeLookup AS (

                                 SELECT * FROM (
                                     VALUES
                                         (1), (2), (3)
                                     ) AS a (Id)

                             )

                             SELECT Offers.*,
                                    OfferBets.*,
                                    SomeLookup.Id AS SomeLookupId, SomeLookup.*
                             FROM   Offers
                             INNER JOIN OfferBets ON Offers.Id = OfferBets.OfferId
                             INNER JOIN SomeLookup ON SomeLookup.Id = Offers.SomeLookupId";

        dbConnection.Open();

        var betDictionary = new Dictionary<int, Offer>();

        var res = dbConnection.Query<Offer, OfferBet, SomeLookup, Offer>(
            sql,
            (offer, bet, someLookup) =>
            {
                if (!betDictionary.TryGetValue(offer.Id, out var offerEntry))
                {
                    offerEntry = offer;
                    offerEntry.Bets = new List<OfferBet>();
                    betDictionary.Add(offer.Id, offerEntry);
                }

                offerEntry.Bets.Add(bet);
                offerEntry.SomeLookup = someLookup;

                return offerEntry;
            },
            splitOn: "Id, SomeLookupId"
        );
    }
}

答案 1 :(得分:0)

这里的答案是为OfferDetails的ID字段添加别名,然后拆分它,所以SQL看起来像

SELECT Offers.*,
       OfferDetails.Id AS OfferDetailId, OfferDetails.*,
       SomeLookup.Id AS SomeLookupId, SomeLookup.*
FROM   Offers
INNER JOIN OfferDetails ON Offers.Id = OfferDetails.OfferId
INNER JOIN SomeLookup ON SomeLookup.Id = Offers.SomeLookupId"

然后splitOn部分看起来像

splitOn: "OfferBetId, SomeLookupId",

这会在Offers中留下重复项,因此我们还需要对结果进行.Distinct()