EntityFramework Core Raw Query再叙注意事项

简介: 前言 最近一直比较忙没有太多时间去更新博客,接下来会一直持续发表相关内容博客,上一篇我们讲到了EF Core中的原始查询,这节我们再来叙述一下原始查询,本文是基于在项目当中用到时发现的问题。 话题 我们通过EF Core原始查询主要是用于一些需要连接多个表进行复杂查询,下面我们来回顾下。

前言

最近一直比较忙没有太多时间去更新博客,接下来会一直持续发表相关内容博客,上一篇我们讲到了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中的并发以及如何解决并发问题,多说一句,个人公众号一直在更新和同步中,后续有可能一些比较简短的内容会只在公众号上更新,为了让用户查阅公众号内容更加便捷也在探索公众号中,希望大家多多关注。 

目录
相关文章
|
缓存 监控 固态存储
在Linux中,如何给最小化安装系统,进行基础优化?
在Linux中,如何给最小化安装系统,进行基础优化?
|
块存储
ceph-deploy部署ceph分部署集群
这篇博客详细介绍了如何使用ceph-deploy工具部署Ceph集群,包括环境准备、配置hosts、免密登录、时间同步、添加块设备、部署mon、mgr组件以及初始化OSD节点的步骤,并提供了在部署过程中可能遇到的问题和解决方案。
982 4
|
Java 数据库连接 测试技术
MyBatis-Plus入门
MyBatis-Plus入门
140 0
|
安全 网络安全 量子技术
网络安全的守护者:漏洞管理、加密技术与安全意识
在数字化时代的浪潮中,网络安全成为维系社会稳定和经济发展的关键因素。本文深入探讨了网络安全的三大支柱:漏洞管理、加密技术和安全意识。通过分析最新的研究数据和案例,揭示了网络威胁的演变趋势,评估了当前防御机制的有效性,并提出了提升个人和组织安全防范能力的策略。旨在为读者提供一套综合性的安全知识框架,以应对不断升级的网络挑战。
行为型模式 - 责任链模式(Chain of Responsibility Pattern)
行为型模式 - 责任链模式(Chain of Responsibility Pattern)
|
消息中间件 存储 NoSQL
RabbitMQ幂等性&优先级队列&惰性对列
RabbitMQ幂等性&优先级队列&惰性对列
168 0
02:输出第二个整数
02:输出第二个整数
169 0
|
存储 缓存 物联网
IL指令速查
IL指令速查
201 0
|
移动开发 weex 开发者
Weex:一个志在满足万物互联的移动端技术解决方案
自2012年以来,WOT品牌大会秉承专注技术、服务技术人员的理念已经成功举办十一届,不仅积累了大量的专家资源,更获得广大IT从业者和技术爱好者的认可和好评,并成为业界重要的技术分享及人脉拓展平台。
1054 0