Skip to content

ISelect能否实现OUTER APPLY #200

Closed
@tky753

Description

@tky753

想要实现这么一个查询

-- 查询歌曲名和第一作者(可能多个作者)
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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions