Entity Framework Core - 访问实体集合的最佳方式? [英] Entity Framework Core - Best way to access a collection on an entity?

查看:15
本文介绍了Entity Framework Core - 访问实体集合的最佳方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的 ASP.NET Core 2.0 + Entity Framework Core 项目:

I have a simple ASP.NET Core 2.0 + Entity Framework Core project:

我有一个名为 ApplicationUser 的实体,它扩展了 Microsoft.AspNet.Identity.IdentityUser,ApplicationUser 有一个名为 Books 的实体的集合代码>.

I have an entity called ApplicationUser, which extends Microsoft.AspNet.Identity.IdentityUser, and the ApplicationUser has a collection of another entity called Books.

但是,当我尝试从 UserManager 检索之后从 ApplicationUser 读取书籍集合时:

However, when I try to read the collection of Books from the ApplicationUser after retrieving it from UserManager:

ApplicationUser user = await _userManager.GetUserAsync(User);
return user.Books;

我得到一个空集合.

如果我这样做:

ApplicationUser user = await _userManager.GetUserAsync(User);
return _context.Users.Include(d => d.Books).FirstOrDefault(u => u == user);

然后我得到了正确的书籍集合.

Then I get the correct collection of Books.

我怀疑这是因为我从 UserManager 检索到的 ApplicationUser 缺少正确的 DbContext.我的问题是,有没有更好的方法来做到这一点?就像能够以某种方式从用户那里获取集合而不必通过 LINQ 遍历 DbContext 一样?会不会有显着的性能提升?

I suspect this is because the ApplicationUser I retrieved from the UserManager lacks the proper DbContext. My question is, is there a better way of doing this? Like somehow being able to just get the collection from the user without having to go through the DbContext with LINQ? Would there be significant performance gain?

最后,阅读 EF Core 的哪些内容可以更好地了解它的工作原理?

Finally, what would be a good read about EF Core to get an understanding of how it works under the hood?

推荐答案

首先,如果要访问数据库中的数据,必须使用 DBContext.其次,您仍然可以从另一个对象访问数据库的唯一方法是该对象是否属于从数据库直接或间接返回的 IQueryable 类型.

First of, if you want to access data from your database, you must use DBContext. Secondly, the only way you can still access the database from another object is if the object was of type IQueryable that was returned directly or indirectly from the database.

例如,以下将返回 IQueryable:

var users = _context.Users.Where(u => u == user);

这意味着您可以访问 users 变量并像这样访问数据库:

This means you can access the users variable and access the database something like this:

var books = users.Select(u => u.Books);

请注意 _userManager.GetUserAsync(User) 函数不返回 IQueryable.这意味着 ApplicationUser 用户 将只包含它要获取的内容(用户对象).简单地使用 user.Books 不会帮助它从数据库中获取数据.此外,如果我没记错的话,GetUserAsync 从当前声明主体而不是数据库中获取其数据.无论哪种方式,当您尝试获取用户时,实体框架也不会自动获取书籍.由于延迟加载,这是 Igor 提到的.https://docs.microsoft.com/en-us/ef/core/querying/related-data

Notice the _userManager.GetUserAsync(User) function does not return an IQueryable. This means that the ApplicationUser user will only contain what it was meant to fetch (the user object). Simply using user.Books will not help it fetch data from the database. Moreover, if I am not mistaken, GetUserAsync gets its data from the current claims principal, not the database. Either way, when you attempt to fetch the user, entity framework will not automatically fetch Books as well. This is as Igor mentioned due to lazy loading. https://docs.microsoft.com/en-us/ef/core/querying/related-data

至于您的方法的优化程度,您可以检查在控制台中运行的确切 SQL 查询.我所展示的上述方式肯定会运行单个查询,因为 ef core 会将这些行放在一起并准确了解要运行的查询.访问相同数据的一种直接方法是

As for how optimized your ways are, you can check the exact SQL query being run in your console. The above way I have shown will surely run a single query since ef core will put those lines together and understand exactly what query to run. A straightforward way to access the same data would be something like

_context.Books.Where(b => b.User == user)

如果这就是您计划使用 user 的全部内容,那么使用 _userManager.GetUserId() 的性能会好一点,因为它只会获得一个值从您的索赔.然后你可以使用:

If this is all you plan to use user for, it would have a little better performance to use _userManager.GetUserId(), since it would only get one value from your claims. Then you can use:

_context.Books.Where(b => b.UserId == userId)

这篇关于Entity Framework Core - 访问实体集合的最佳方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆