Ef Core花里胡哨系列(11) ef8 无实体查询,你好!

发布时间 2024-01-04 15:01:17作者: 胖纸不争

Ef Core花里胡哨系列(11) ef8 无实体查询,你好!

EF7 引入了返回标量类型的原始 SQL 查询。 这在 EF8 中得到了增强,包括返回任何可映射 CLR 类型的原始 SQL 查询,而无需在 EF 模型中包括该类型。

使用非映射类型的查询是使用 SqlQuerySqlQueryRaw 执行的。 前者使用字符串内插来参数化查询,这有助于确保所有非常量值都被参数化。

var result = _dbContext.Database.SqlQuery<Blog>($"select * from {typeof(Blog).Name}").ToList();

非常振奋人心的是,SqlQuery的得到的结果是一个IQueryable,也就是说,可以无缝对接Linq!

所以你可以这样,在Sql中直接写上你的条件:

var cutoffDate = new DateOnly(2022, 1, 1);
var summaries =
    await context.Database.SqlQuery<PostSummary>(
            @$"SELECT b.Name AS BlogName, p.Title AS PostTitle, p.PublishedOn
               FROM Posts AS p
               INNER JOIN Blogs AS b ON p.BlogId = b.Id
               WHERE p.PublishedOn >= {cutoffDate}")
        .ToListAsync();

或者这样,使用Sql拼接表,再用Linq进行筛选:

var summariesIn2022 =
    await context.Database.SqlQuery<PostSummary>(
            @$"SELECT b.Name AS BlogName, p.Title AS PostTitle, p.PublishedOn
               FROM Posts AS p
               INNER JOIN Blogs AS b ON p.BlogId = b.Id")
        .Where(p => p.PublishedOn >= cutoffDate && p.PublishedOn < end)
        .ToListAsync();

到目前为止,所有查询都是直接针对表执行的。 SqlQuery 也可用于在不映射 EF 模型中的视图类型的情况下从视图返回结果。 例如:

var summariesFromView =
    await context.Database.SqlQuery<PostSummary>(
            @$"SELECT * FROM PostAndBlogSummariesView")
        .Where(p => p.PublishedOn >= cutoffDate && p.PublishedOn < end)
        .ToListAsync();

甚至是函数:

var summariesFromFunc =
    await context.Database.SqlQuery<PostSummary>(
            @$"SELECT * FROM GetPostsPublishedAfter({cutoffDate})")
        .Where(p => p.PublishedOn < end)
        .ToListAsync();

亦或者是存储过程:

var summariesFromStoredProc =
    await context.Database.SqlQuery<PostSummary>(
            @$"exec GetRecentPostSummariesProc")
        .ToListAsync();