前言
最近一直比較忙沒有太多時間去更新部落格,接下來會一直持續發表相關内容部落格,上一篇我們講到了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中的并發以及如何解決并發問題,多說一句,個人公衆号一直在更新和同步中,後續有可能一些比較簡短的内容會隻在公衆号上更新,為了讓使用者查閱公衆号内容更加便捷也在探索公衆号中,希望大家多多關注。
你所看到的并非事物本身,而是經過诠釋後所賦予的意義