2013-06-18 3 views
16

Sto provando ad usare la funzione Multi-mapping di dapper per restituire un elenco di Album e artista associato e Genere.Quando si usano le API multi-mapping assicuratevi di impostare il parametro splitOn se avete chiavi diverse da Id "," splitOn

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

Ho controllato per soluzione per quanto riguarda questo, non di ha funzionato. Qualcuno può per favore farmi sapere dove ho sbagliato?

Grazie @Alex :) Ma sono ancora colpito. Questo è quello che ho fatto:

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') 

Come suggerito da voi ho cambiato la query per:

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

Ora sto usando splitOn per GenreId e ArtistId. Ho ancora lo stesso errore. Per favore aiuto.

risposta

28

È necessario includere la colonna che si desidera dividere nella query di selezione. La tua seleziona tutte le altre proprietà - quindi Dapper non trova una colonna corrispondente per dividere gli oggetti.

Vostri criteri dovrebbe probabilmente essere qualcosa di simile:

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

Sam ha scritto una risposta eccellente per il multi mappature e l'opzione splitOn: https://stackoverflow.com/a/7478958/1028323

Edit: Se la query è come detto in precedenza, è Dovrò dividermi su GenreId e ArtistId.

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

I tubi sono per l'inizio di un nuovo POCO che si sta tentando di mappare. Quindi i parametri SplitOn sarebbero GenreId e ArtistId.

Edit2: Il problema è il tuo POCO Album. Si specifica ArtistId e GenreId come proprietà ma in pratica appartengono ai rispettivi 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; } 
    } 

e

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

dovrebbe fare il trucco. Non è necessario GenreId e ArtistId perché si dispone di un riferimento a tali oggetti in Albums.

+0

dopo aver apportato le modifiche suggerite dall'utente, non ha funzionato. Ho modificato la query considerando solo la classe Artist e Album. query = "SELEZIONA AR.ArtistId, AR.Name, AL.AlbumId, AL.Prezzo, AL.Titolo, AL.AlbumArtUrl FROM Artista AR INNER JOIN Album AL ON AR.ArtistId = AL.AlbumId"; var item = connection.Query (query, (album, artista) => {album.artista = artista; ritorno album;}, commandType: CommandType.Text, splitOn: "ArtistId"); Ancora non ha funzionato – user2497013

+0

@ user2497013 Vedi la mia modifica. Il modo più semplice è quello di formare il tuo SQL che corrisponda ai POCO che stai cercando di abbinare nell'ordine giusto. Attualmente, stai dividendo su ArtistId - che dice a Dapper di provare a mappare tutte le proprietà dopo ArtistId su un POCO che non è corretto. – Alex

+0

Ho cambiato la query ma ancora non funziona. var query = @ "SELEZIONA AL.AlbumId, AL.Title, AL.Price, AL.AlbumArtUrl, GE.GenreId, GE.Name, GE.Description, AR.ArtistId, AR.Name FROM Album AL INNER JOIN Artista AR SU AR .ArtistId = AL.ArtistId INNER JOIN Genere GE ON GE.GenreId = AL.GenreId "; var res = connection.Query (query, (album, genere, artista) => {album.Genre = genere; album.artista = artista; ritorno album;}, commandType: CommandType .Text, splitOn: "GenreId, ArtistId"); Per favore aiuto. – user2497013

-2

Alcune scene "Album" e "Genere" hanno tutte una proprietà che il suo nome è uguale. SO ... Click here can help you.