Al usar las API de mapeo múltiple, asegúrese de configurar el parametro splitOn si tiene claves que no sean Id "," splitOn "

dapper

Pregunta

Estoy intentando usar la función de mapeo múltiple de dapper para devolver una lista de Álbum y artista y género asociados.

public class Artist
{
public virtual int ArtistId { get; set; }
public virtual string Name { get; set; }
}    


public class Genre
{
public virtual int GenreId { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
}


public class Album
{
public virtual int AlbumId { get; set; }
public virtual int GenreId { get; set; }
public virtual int ArtistId { get; set; }
public virtual string Title { get; set; }
public virtual decimal Price { get; set; }
public virtual string AlbumArtUrl { get; set; }
public virtual Genre Genre { get; set; }
public virtual Artist Artist { get; set; }
}


var query = @"SELECT AL.Title, AL.Price, AL.AlbumArtUrl, GE.Name, GE.[Description], AR.Name FROM Album AL INNER JOIN Genre GE ON AL.GenreId = GE.GenreId INNER JOIN Artist AR ON AL.ArtistId = AL.ArtistId";

var res = connection.Query<Album, Genre, Artist, Album>(query, (album, genre, artist) => { album.Genre = genre; album.Artist = artist; return album; }, commandType: CommandType.Text, splitOn: "ArtistId, GenreId");

He verificado la solución con respecto a esto, no funcionó. ¿Puede alguien decirme por favor dónde me he equivocado?

Gracias @Alex :) Pero todavía estoy golpeado. Esto es lo que he hecho:

CREATE TABLE Artist
(
ArtistId INT PRIMARY KEY IDENTITY(1,1)
,Name VARCHAR(50)
)

CREATE TABLE Genre
(
    GenreId INT PRIMARY KEY IDENTITY(1,1)
    ,Name VARCHAR(20)
    ,[Description] VARCHAR(1000)
)

CREATE TABLE Album
(
    AlbumId INT PRIMARY KEY IDENTITY(1,1)
    ,GenreId INT FOREIGN KEY REFERENCES Genre(GenreId)
    ,ArtistId INT FOREIGN KEY REFERENCES Artist(ArtistId)
    ,Title VARCHAR(100)
    ,Price FLOAT
    ,AlbumArtUrl VARCHAR(300) 
)

INSERT INTO Artist(Name) VALUES ('Jayant')
INSERT INTO Genre(Name,[Description]) VALUES ('Rock','Originally created during school days. The year was.....I guess 1998')
DECLARE @gen_id INT
        ,@art_id INT
SET @gen_id = (SELECT MAX(GenreId) FROM Genre)
SET @art_id = (SELECT MAX(ArtistId) FROM Artist)
INSERT INTO Album(GenreId,ArtistId,Title,Price,AlbumArtUrl) VALUES (@gen_id,@art_id,'I go mad for you',200,'http://asha4u.com/IGoMad')

Como sugirió usted, cambié la consulta a:

var query = @"SELECT AL.AlbumId, AL.Title, AL.Price, AL.AlbumArtUrl, GE.GenreId, GE.Name, GE.Description, AR.ArtistId, AR.Name FROM Album AL INNER JOIN Artist AR ON AR.ArtistId = AL.ArtistId INNER JOIN Genre GE ON GE.GenreId = AL.GenreId";

var res = connection.Query<Album, Genre, Artist, Album>(query, (album, genre, artist) => { album.Genre = genre; album.Artist = artist; return album; }, commandType: CommandType.Text, splitOn: "GenreId, ArtistId");

Ahora estoy usando splitOn para GenreId y ArtistId. Todavía recibo el mismo error. Por favor ayuda.

Respuesta popular

Debe incluir la columna que desea dividir en su consulta de selección. El suyo solo selecciona todas las demás propiedades, por lo que Dapper no encuentra una columna coincidente para dividir los objetos.

Su consulta probablemente debería ser algo así:

var query = @"SELECT AlbumId, Title, Price, AlbumArtUrl, GenreId, Name, Description , ArtistId, Name ......" etc

Sam escribió una excelente respuesta para las asignaciones múltiples y la opción splitOn: https://stackoverflow.com/a/7478958/1028323

Editar: Si su consulta es como se mencionó anteriormente, tendrá que dividirse en GenreId y ArtistId.

 AlbumId, Title, Price, AlbumArtUrl | GenreId, Name, Description | ArtistId, Name

Las canalizaciones son para el inicio de un nuevo POCO que está intentando mapear. Así que los parámetros de SplitOn serían GenreId y ArtistId.

Edit2: El problema es tu Album POCO. Usted especifica ArtistId y GenreId como propiedades pero básicamente pertenecen a sus respectivos POCO's .

public class Album
    {
        public virtual int AlbumId { get; set; }
        public virtual string Title { get; set; }
        public virtual decimal Price { get; set; }
        public virtual string AlbumArtUrl { get; set; }
        public virtual Genre Genre { get; set; }
        public virtual Artist Artist { get; set; }
    }

y

var sql = @"SELECT AL.AlbumId
                 , AL.Title
                 , AL.Price
                 , AL.AlbumArtUrl
                 , GE.GenreId
                 , GE.Name
                 , GE.Description
                 , AR.ArtistId
                 , AR.Name 
            FROM Album AL 
      INNER JOIN Artist AR ON AR.ArtistId = AL.ArtistId 
      INNER JOIN Genre GE ON GE.GenreId = AL.GenreId";

using (var conn = connFactory.OpenConnection())
{
    var res = conn.Query<Album, Genre, Artist, Album>(sql, (album, genre, artist) =>
    {
        album.Genre = genre;
        album.Artist = artist;
        return album;
    }, splitOn: "GenreId,ArtistId");
}

debe hacer el truco No necesita GenreId y ArtistId todos modos porque tiene una referencia a esos objetos en Albums .



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow