前言
最近一直比較忙沒有太多時間去更新博客,接下來會一直持續發表相關內容博客,上一篇我們講到了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中的並發以及如何解決並發問題,多說一句,個人公眾號一直在更新和同步中,后續有可能一些比較簡短的內容會只在公眾號上更新,為了讓用戶查閱公眾號內容更加便捷也在探索公眾號中,希望大家多多關注。