Closed
Description
想要实现这么一个查询
-- 查询歌曲名和第一作者(可能多个作者)
SELECT A.Name as Name, B.Name as AuthorName FROM Song A
OUTER APPLY(SELECT TOP 1 Name FROM Author WHERE A.ID = SongId Order By Id) B
OUTER APPLY
没有在FreeSql的ISelect找到相应实现,也可能是我找的不够仔细,望指教。
如果没有的话,个人有一些小想法,看看可不可行.
想法一:
为ISelect
提供FromRaw
方法,允许在Frow后面插入raw sql
为ISelectFromExpression
提供Ignore<TX>
方法,忽略对From实体的动作
var sql = fsql.Select<Song>()
.From<Author>((a,b)=>a.Ignore<Author>()) //新增Ignore方法实现忽略对Author表的From动作
.FromRaw("OUTER APPLY(SELECT TOP 1 Name FROM Author WHERE A.ID = SongId Order By Id) b")
.ToSql((a, b) => new SongDto
{
Name = a.Name,
AuthorName = b.Name
});
// 不过FrowRaw和WithSql有歧义,这是个问题,可以想想换个名字
想法二:
为ISelectFromExpression
提供WithSql<TX>(string)
方法,自定义对From实体的关联动作
var sql = fsql.Select<Song>()
.From<Author>((a,b)=>a.WithSql<Author>("OUTER APPLY(SELECT TOP 1 Name FROM Author WHERE A.ID = SongId Order By Id)"))
.ToSql((a, b) => new SongDto
{
Name = a.Name,
AuthorName = b.Name
});
想法三:
允许Join子ISelect,并且可以自定义 JOIN 关键字
var sql = fsql.Select<Song>()
.From<Author>((a,b)=>
a.WiseJoin(a1 => fsql.Select<Author>().Take(1).Where(b1 => a1.Id == b1.SongId), "OUTER APPLY")
.ToSql((a, b) => new SongDto
{
Name = a.Name,
AuthorName = b.Name
});
// 这个感觉很难吧,要解析一个子ISelect
//灵感来源于SqlKata 的
public Query Join(string table, Func<Join, Join> callback, string type = "inner join")
粗陋想法,希望能够助力FreeSql变得越来越强大。👍
Metadata
Metadata
Assignees
Labels
No labels