EntityFramework Core Raw Query再叙注意事项
前言
最近一直比较忙没有太多时间去更新博客,接下来会一直持续发表相关内容博客,上一篇我们讲到了EF Core中的原始查询,这节我们再来叙述一下原始查询,本文是基于在项目当中用到时发现的问题。
话题
我们通过EF Core原始查询主要是用于一些需要连接多个表进行复杂查询,下面我们来回顾下。我们定义一个ViewModel。
public class BlogViewModel { public string Name { get; set; } public string Url { get; set; } public string Title { get; set; } public string Content { get; set; } }
我们将表Blog和Post表进行连接查询出两个表中的列,定义如下接口。
BlogViewModel GetBlog(int BlogId);
接下来我们来写SQL语句。
private EFCoreContext _efCoreContext; public BlogRepository(EFCoreContext efCoreContext) : base(efCoreContext) { _efCoreContext = efCoreContext; } public BlogViewModel GetBlog(int BlogId) { var sql = @"SELECT Name, Url, Content, Title FROM dbo.Blog INNER JOIN dbo.Post ON dbo.Post.BlogId = dbo.Blog.Id WHERE dbo.Blog.Id = {0}"; var blogSingle = _efCoreContext.Set<BlogViewModel>().FromSql(sql, BlogId); return blogSingle.ToList().FirstOrDefault(); }
然后我们在控制器中进行查询。
public IActionResult Index() { var blog = _blogRepository.GetBlog(2); return Ok(); }
此时会出现如下错误:
Cannot create a DbSet for 'BlogViewModel' because this type is not included in the model for the context.
我们知道当我们利用原始查询出来的实体非EF Entity,而是由我们自定义的ViewModel。所以才会出现BlogViewModel未在EF上下文中,所以为了解决上述问题我们需要在EF上下文中定义ViewModel,如下:
public class EFCoreContext : DbContext { public EFCoreContext(DbContextOptions options) : base(options) { } public DbSet<BlogViewModel> BlogViewModels { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.AddEntityConfigurationsFromAssembly(GetType().GetTypeInfo().Assembly); } }
然后我们在利用SQL查询时需要用到上述BlogViewModels。如下:
public BlogViewModel GetBlog(int BlogId) { var sql = @"SELECT Name, Url, Content, Title FROM dbo.Blog INNER JOIN dbo.Post ON dbo.Post.BlogId = dbo.Blog.Id WHERE dbo.Blog.Id = {0}"; var blogSingle = _efCoreContext.BlogViewModels.FromSql(sql, BlogId); return blogSingle.ToList().FirstOrDefault();
}
我们再来看看运行结果,结果依然出错,错误显示如下:
其他信息: The entity type 'BlogViewModel' requires a primary key to be defined.
根据提示我们再将BlogViewModel添加一个主键。
public class BlogViewModel { public int Id { get; set; } public string Name { get; set; } public string Url { get; set; } public string Title { get; set; } public string Content { get; set; } }
当然此时我们在写SQL时也要返回主键Id。
var sql = @"SELECT b.Id, b.Name, b.Url, p.Content, p.Title FROM dbo.Blog AS b INNER JOIN dbo.Post AS p ON p.BlogId = b.Id WHERE b.Id = {0}";
此时我们再来运行看看。
总结
本节我们探讨了EF Core中进行原始查询需要注意的地方,我们再来做一个总结,当我们利用EF Core返回一个ViewModel的话,此时我们需要将ViewModel定义在上文中,同时在ViewModel中需要定义一个主键,否则会出错。好了,今天到此结束,我们下一篇会讲讲EF Core中的并发以及如何解决并发问题,多说一句,个人公众号一直在更新和同步中,后续有可能一些比较简短的内容会只在公众号上更新,为了让用户查阅公众号内容更加便捷也在探索公众号中,希望大家多多关注。

为了方便大家在移动端也能看到我分享的博文,现已注册个人公众号,扫描上方左边二维码即可,欢迎大家关注,有时间会及时分享相关技术博文。
感谢花时间阅读此篇文章,如果您觉得这篇文章你学到了东西也是为了犒劳下博主的码字不易不妨打赏一下吧,让楼主能喝上一杯咖啡,在此谢过了!
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!
本文版权归作者和博客园共有,来源网址:http://www.cnblogs.com/CreateMyself)/欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构