我正在尝试使用dapper的多映射功能来返回相册和相关艺术家和流派的列表。
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");
我已经检查了有关此问题的解决方案,但没有成功。谁能告诉我哪里出错了?
谢谢@Alex :)但我仍然感到震惊。这就是我所做的:
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')
根据您的建议,我将查询更改为:
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");
现在我正在为GenreId和ArtistId使用splitOn。我仍然得到同样的错误。请帮忙。
答案 0 :(得分:39)
您需要在选择查询中包含要拆分的列。您只需选择所有其他属性 - 因此Dapper
找不到匹配的列来拆分对象。
你的查询应该是这样的:
var query = @"SELECT AlbumId, Title, Price, AlbumArtUrl, GenreId, Name, Description , ArtistId, Name ......" etc
Sam为多映射和splitOn选项写了一个很好的答案: https://stackoverflow.com/a/7478958/1028323
编辑:如果您的查询如上所述,您将必须拆分GenreId和ArtistId。
AlbumId, Title, Price, AlbumArtUrl | GenreId, Name, Description | ArtistId, Name
管道用于启动您尝试映射的新POCO。因此SplitOn
参数将是GenreId和ArtistId。
Edit2:问题是您的POCO Album
。您将ArtistId
和GenreId
指定为属性,但它们基本上属于各自的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; }
}
和
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");
}
应该做的伎俩。您无论如何都不需要GenreId
和ArtistId
,因为您在Albums
中有对这些对象的引用。
答案 1 :(得分:1)
我遇到了同样的问题。 这是技巧和示例。
public abstract class BaseEntity
{
[Key]
public int Id { get; set; }
}
public class Category : BaseEntity
{
public string Name { get; set; }
}
public class Status : BaseEntity
{
public string Name { get; set; }
}
public class User : BaseEntity
{
public string Name { get; set; }
public string Surname { get; set; }
public bool Active { get; set; }
}
public class TodoItem : BaseEntity
{
public string Title { get; set; }
public string Message { get; set; }
public Status Status { get; set; }
public Category Category { get; set; }
public User User { get; set; }
public DateTime CreatedOn { get; set; }
}
使用
string sql = @"select
t.Id,
t.Title,
t.Message,
t.CreatedOn,
s.Id as Id,
s.Name,
c.Id as Id,
c.Name,
u.Id as Id,
u.Name,
u.Surname,
u.Active
from ToDoItem t
inner join [Status] s on (t.StatusId = s.Id)
inner join [Category] c on (t.CategoryId = c.Id)
inner join [User] u on (t.AssignUserId = u.Id)";
var result = connection.Query<TodoItem, Status, Category, User, TodoItem>
(sql, (todoItem, status, category, user) =>
{
todoItem.Status = status;
todoItem.Category = category;
todoItem.User = user;
return todoItem;
},splitOn: "Id,Id,Id,Id");
这是把戏 splitOn:“ Id,Id,Id,Id”