Dapper One-To-Many con múltiples tablas

.net dapper

Pregunta

Tengo a Dapper recuperando mis datos así:

using (var dbConnection = new SqlConnection(_connectionString))
{
    const string sql =
                "SELECT Offers.*, " +
                "       OfferDetails.*," +
                "       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>();

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

                    offerEntry.Bets.Add(bet);

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

Debería devolver una lista de Ofertas que contienen una lista de OfferDetails y una SomeLookup.

Lo que obtengo es una lista de pedidos para cada objeto OrderDetails. Devuelve el conjunto de datos unido y completa un Pedido para cada registro (y cada uno tiene 1 elemento OrderDetails en la colección).

¿Qué he hecho mal en la detección de duplicados?

Respuesta popular

Supongo que OfferDetails / OfferBets también contiene una columna llamada Id en adición a OfferId y esta columna se coloca antes de OfferId y esto se confunde. Entonces, si cambia el parámetro splitOn a splitOn: "Id, SomeLookupId" podría funcionar.

[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"
        );
    }
}


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué