C# 使用多重映射API时,如果您有Id以外的键,请确保设置splitOn参数&引用;斯普利顿
我正在尝试使用dapper的多重映射功能来返回专辑列表以及相关的艺术家和流派C# 使用多重映射API时,如果您有Id以外的键,请确保设置splitOn参数&引用;斯普利顿,c#,dapper,C#,Dapper,我正在尝试使用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; se
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");
根据您的建议,我将查询更改为:
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");
var query=@“从相册中选择AL.AlbumId、AL.Title、AL.Price、AL.AlbumArtUrl、GE.GenreId、GE.Name、GE.Description、AR.ArtistId、AR.Name AL-in-JOIN-Artist-AR-ON-AR.ArtistId=AL.ArtistId-in-GenreId=AL.GenreId”;
var res=connection.Query(查询,(唱片集,流派,艺术家)=>{album.genre=genre;唱片集.艺术家=艺术家;返回唱片集;},commandType:commandType.Text,splitOn:“GenreId,ArtistId”);
现在我正在为GenreId和ArtistId使用splitOn。我仍然会犯同样的错误。请提供帮助。您需要在select查询中包含要拆分的列。您的属性只是选择所有其他属性,因此
Dapper
没有找到匹配的列来分割对象
您的查询可能如下所示:
var query = @"SELECT AlbumId, Title, Price, AlbumArtUrl, GenreId, Name, Description , ArtistId, Name ......" etc
Sam为多重映射和splitOn选项写了一个极好的答案:
编辑:如果您的查询如上所述,则必须在GenreId和ArtistId上进行拆分
AlbumId, Title, Price, AlbumArtUrl | GenreId, Name, Description | ArtistId, Name
这些管道是用于您尝试映射的新POCO的开始。因此,SplitOn
参数将是GenreId和ArtistId
Edit2:问题是你的POCO相册
。您可以指定ArtistId
和GenreId
作为属性,但它们基本上属于各自的POCO
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=@“选择AL.AlbumId
,AL.Title
,艾尔·普莱斯
,AL.AlbumArtUrl
,GE.GenreId
,GE.Name
,GE.说明
,AR.ArtistId
,AR.名称
来自专辑AL
内部连接艺术家AR ON AR.ArtistId=AL.ArtistId
内部连接类型GE ON GE.GenreId=AL.GenreId”;
使用(var conn=connFactory.OpenConnection())
{
var res=conn.Query(sql,(专辑、流派、艺术家)=>
{
专辑风格=风格;
专辑。艺术家=艺术家;
返回相册;
},斯普利顿:“根里德,艺术家”);
}
我们应该做到这一点。无论如何,您不需要GenreId
和ArtistId
,因为您在相册中引用了这些对象
我也遇到了同样的问题。
这里是技巧和例子
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");
stringsql=@“选择
t、 身份证,
t、 头衔,
t、 信息,
t、 CreatedOn,
s、 Id作为Id,
s、 名字,
c、 Id作为Id,
c、 名字,
u、 Id作为Id,
u、 名字,
u、 姓,
u、 活跃的
从今
内部联接[Status]s打开(t.StatusId=s.Id)
内部联接[Category]c on(t.CategoryId=c.Id)
内部连接[User]u on(t.AssignUserId=u.Id)”;
var result=connection.Query
(sql,(todoItem、状态、类别、用户)=>
{
todoItem.Status=状态;
todoItem.Category=类别;
todoItem.User=用户;
返回doitem;
},splitOn:“Id,Id,Id,Id”);
这里有一个技巧拆分:“Id,Id,Id,Id”在做出您建议的更改后,它仍然不起作用。我更改了查询,只考虑了艺术家和专辑类。query=“选择AR.ArtistId、AR.Name、AL.AlbumId、AL.Price、AL.Title、AL.AlbumArtUrl从艺术家AR内部加入AR.ArtistId=AL.AlbumId上的Album AL”;var item=connection.Query(Query,(album,artist)=>{album.artist=artist;return album;},commandType:commandType.Text,splitOn:“ArtistId”);它仍然没有work@user2497013请参阅我的编辑。最简单的方法是形成SQL,使其与您试图以正确顺序匹配的POCO相匹配。目前,您正在使用ArtistId进行拆分-这告诉Dapper尝试将ArtistId之后的所有属性映射到一个不正确的POCO。我更改了查询,但仍然无法工作。var query=@“从相册中选择AL.AlbumId、AL.Title、AL.Price、AL.AlbumArtUrl、GE.GenreId、GE.Name、GE.Description、AR.ArtistId、AR.Name 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=genre;唱片集.艺术家=艺术家;返回唱片集;},commandType:commandType.Text,splitOn:“GenreId,ArtistId”);请帮忙。问题在于你的POCO。您需要从相册中删除GenreId和ArtistId,否则Dapper将以未定义的行为结束:)非常感谢您的努力。。最后代码成功了:)将ArtistId和GenreId从POCO专辑中删除就成功了。干杯
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");