Dapper SQL Join table 成另一个
Dapper SQL Join table into another
这里是新手。我有以下 2 个表。
一张专辑:
另一个是歌曲:
所有这些歌曲都属于“Freedom”专辑。
在 api 调用中,我使用 dapper 显示所有相册,这很好。
[HttpGet("[action]/{id}")]
public async Task<IActionResult> GetSingleAlbumViaDapper(int id)
{
var sql = "SELECT * FROM Albums WHERE Id = @AlbumId";
var album = (await _dbDapper.QueryAsync<Album>(sql, new { AlbumId = id })).SingleOrDefault();
}
结果如下:
但我想加入与这张专辑相关的歌曲。
我已经尝试了以下但它不起作用,知道为什么吗?
[HttpGet("[action]/{id}")]
public async Task<IActionResult> GetSingleAlbumViaDapper(int id)
{
var sql = "SELECT * FROM Albums WHERE Id = @AlbumId JOIN Songs in Songs on Albums.Songs";
var album = (await _dbDapper.QueryAsync<Album>(sql, new { AlbumId = id })).SingleOrDefault();
}
它说的是:Incorrect syntax near the keyword 'JOIN'
。
您加入 table 的方式有误。先加入,再过滤(where-part)
正确的查询应该是这样的
SELECT *
FROM Albums a
JOIN Songs s
ON s.AlbumId = a.Id
WHERE a.Id = @AlbumId;
更新。由于您仅在第二个查询中查找歌曲,因此从您的 table 场景中我看到此处不需要加入。您已经将 album.id 传递给查询。试试这个,让我知道结果
SELECT *
FROM Songs s
WHERE s.AlbumId = @AlbumId;
尝试按如下方式更改您的连接查询:
SELECT a.* FROM Albums as a inner join Songs as s on s.AlbumId = a.Id WHERE a.Id = @AlbumId
您需要使用 Dapper 的连接语法。
我假设您有一首歌曲 class,我还假设您的专辑构造函数创建了歌曲列表。然后你会像下面那样做,告诉 dapper 期待专辑和歌曲以及 return 专辑。数据应该根据歌曲的 Id 进行拆分,这就是 splitOn 参数的用途。这是凭记忆输入的,缺少信息,因此可能需要一些调整。
var sql = "SELECT * FROM Albums AS a INNER JOIN Songs AS s ON s.AlbumId = a.Id WHERE a.Id = @AlbumId";
Album foundAlbum = null;
_ = (await _dbDapper.QueryAsync<Album, Song, Album>(sql, (album, song) =>
{
if (foundAlbum is null)
{
foundAlbum = album;
}
foundAlbum.Songs.Add(song);
return album;
}, splitOn : "Id", new { AlbumId = id }));
// Use foundAlbum here....
不需要查询的 return 值,因为找到的专辑在 foundAlbum 变量中。查询找到多行,但这只是因为专辑中有多首歌曲。
这里是新手。我有以下 2 个表。 一张专辑:
另一个是歌曲:
所有这些歌曲都属于“Freedom”专辑。 在 api 调用中,我使用 dapper 显示所有相册,这很好。
[HttpGet("[action]/{id}")]
public async Task<IActionResult> GetSingleAlbumViaDapper(int id)
{
var sql = "SELECT * FROM Albums WHERE Id = @AlbumId";
var album = (await _dbDapper.QueryAsync<Album>(sql, new { AlbumId = id })).SingleOrDefault();
}
结果如下:
但我想加入与这张专辑相关的歌曲。 我已经尝试了以下但它不起作用,知道为什么吗?
[HttpGet("[action]/{id}")]
public async Task<IActionResult> GetSingleAlbumViaDapper(int id)
{
var sql = "SELECT * FROM Albums WHERE Id = @AlbumId JOIN Songs in Songs on Albums.Songs";
var album = (await _dbDapper.QueryAsync<Album>(sql, new { AlbumId = id })).SingleOrDefault();
}
它说的是:Incorrect syntax near the keyword 'JOIN'
。
您加入 table 的方式有误。先加入,再过滤(where-part)
正确的查询应该是这样的
SELECT *
FROM Albums a
JOIN Songs s
ON s.AlbumId = a.Id
WHERE a.Id = @AlbumId;
更新。由于您仅在第二个查询中查找歌曲,因此从您的 table 场景中我看到此处不需要加入。您已经将 album.id 传递给查询。试试这个,让我知道结果
SELECT *
FROM Songs s
WHERE s.AlbumId = @AlbumId;
尝试按如下方式更改您的连接查询:
SELECT a.* FROM Albums as a inner join Songs as s on s.AlbumId = a.Id WHERE a.Id = @AlbumId
您需要使用 Dapper 的连接语法。 我假设您有一首歌曲 class,我还假设您的专辑构造函数创建了歌曲列表。然后你会像下面那样做,告诉 dapper 期待专辑和歌曲以及 return 专辑。数据应该根据歌曲的 Id 进行拆分,这就是 splitOn 参数的用途。这是凭记忆输入的,缺少信息,因此可能需要一些调整。
var sql = "SELECT * FROM Albums AS a INNER JOIN Songs AS s ON s.AlbumId = a.Id WHERE a.Id = @AlbumId";
Album foundAlbum = null;
_ = (await _dbDapper.QueryAsync<Album, Song, Album>(sql, (album, song) =>
{
if (foundAlbum is null)
{
foundAlbum = album;
}
foundAlbum.Songs.Add(song);
return album;
}, splitOn : "Id", new { AlbumId = id }));
// Use foundAlbum here....
不需要查询的 return 值,因为找到的专辑在 foundAlbum 变量中。查询找到多行,但这只是因为专辑中有多首歌曲。