Yur*_* N. 1 c# entity-framework entity-framework-core
我们来看看简单的类示例:
public class Book
{
[Key]
public string BookId { get; set; }
public List<BookPage> Pages { get; set; }
public string Text { get; set; }
}
public class BookPage
{
[Key]
public string BookPageId { get; set; }
public PageTitle PageTitle { get; set; }
public int Number { get; set; }
}
public class PageTitle
{
[Key]
public string PageTitleId { get; set; }
public string Title { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
所以,如果我想获得所有PageTitiles,如果我只知道BookId,我需要写一些包含,如下所示:
using (var dbContext = new BookContext())
{
var bookPages = dbContext
.Book
.Include(x => x.Pages)
.ThenInclude(x => x.PageTitle)//.ThenInclude(x => x.Select(y => y.PageTitle)) Shouldn't use in EF Core
.SingleOrDefault(x => x.BookId == "some example id")
.Pages
.Select(x => x.PageTitle);
}
Run Code Online (Sandbox Code Playgroud)
如果我想让PageTitles与其他书籍连接,我需要再次重写这个方法,除了BookId之外没有任何改变!这是使用数据库的非常低效的方法,在这个例子中我有3个类,但是如果我有数百个类,嵌套到非常深的层次,那么工作会非常缓慢和不舒服.
我应该如何组织使用我的数据库,以避免许多包含和冗余查询?
问题1:我Includes每次都要添加一堆.
好吧,由于您必须在EF中明确包含相关数据,因此无法解决这个问题,但您可以轻松创建扩展方法以使其更清晰:
public static IQueryable<Book> GetBooksAndPages(this BookContext db)
{
return db.Book.Include(x => x.Pages);
}
public static IQueryable<Book> GetBooksAndPagesAndTitles(this BookContext db)
{
return GetBooksAndPages(db).ThenInclude(p => p.PageTitle)
}
Run Code Online (Sandbox Code Playgroud)
然后你可以这样做:
var bookPages = dbContext
.GetBooksAndPagesAndTitles()
.SingleOrDefault(x => x.BookId == "some example id")
.Pages
.Select(x => x.PageTitle);
Run Code Online (Sandbox Code Playgroud)
问题2:我必须多次为不同的ID编写此查询.
为什么不将它重构为带bookId参数的方法?
public IEnumerable<PageTitle> GetPageTitlesForBook(BookContext dbContext, int bookId)
{
return dbContext
.GetBooksAndPagesAndTitles()
.SingleOrDefault(x => x.BookId == bookId)
.Pages
.Select(x => x.PageTitle);
}
Run Code Online (Sandbox Code Playgroud)
底线 - 如果您发现自己多次编写相同的内容,那么这是将代码重构为可重复使用的较小方法的绝佳机会.
| 归档时间: |
|
| 查看次数: |
3641 次 |
| 最近记录: |