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中的并发以及如何解决并发问题,多说一句,个人公众号一直在更新和同步中,后续有可能一些比较简短的内容会只在公众号上更新,为了让用户查阅公众号内容更加便捷也在探索公众号中,希望大家多多关注。 





本文转自Jeffcky博客园博客,原文链接:http://www.cnblogs.com/CreateMyself/p/6287537.html,如需转载请自行联系原作者


目录
相关文章
|
3月前
|
XML 缓存 API
【Azure API 管理】使用APIM进行XML内容读取时遇见的诡异错误 Expression evaluation failed. Object reference not set to an instance of an object.
【Azure API 管理】使用APIM进行XML内容读取时遇见的诡异错误 Expression evaluation failed. Object reference not set to an instance of an object.
flowable项目报错:java.sql.SQLSyntaxErrorException: Table ‘psr_flowable_test.act_ge_property’ doesn’t exi
flowable项目报错:java.sql.SQLSyntaxErrorException: Table ‘psr_flowable_test.act_ge_property’ doesn’t exi
165 0
|
开发框架 算法 .NET
C#/Entity Frame Core使用Linq进行分页.skip().Take()的使用方法
C#/Entity Frame Core使用Linq进行分页.skip().Take()的使用方法
294 0
C#/Entity Frame Core使用Linq进行分页.skip().Take()的使用方法