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中的並發以及如何解決並發問題,多說一句,個人公眾號一直在更新和同步中,后續有可能一些比較簡短的內容會只在公眾號上更新,為了讓用戶查閱公眾號內容更加便捷也在探索公眾號中,希望大家多多關注。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM