Ef Core花里胡哨系列(11) ef8 无实体查询,你好!
EF7 引入了返回标量类型的原始 SQL 查询。 这在 EF8 中得到了增强,包括返回任何可映射 CLR 类型的原始 SQL 查询,而无需在 EF 模型中包括该类型。
使用非映射类型的查询是使用 SqlQuery 或 SqlQueryRaw 执行的。 前者使用字符串内插来参数化查询,这有助于确保所有非常量值都被参数化。
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.PublishedOnFROM Posts AS pINNER JOIN Blogs AS b ON p.BlogId = b.IdWHERE p.PublishedOn >= {cutoffDate}").ToListAsync();
或者这样,使用Sql拼接表,再用Linq进行筛选:
var summariesIn2022 =await context.Database.SqlQuery<PostSummary>(@$"SELECT b.Name AS BlogName, p.Title AS PostTitle, p.PublishedOnFROM Posts AS pINNER 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();