如何告诉DBContext的Find方法,它应该急切地加载导航属性/实体?
我有以下代码,它将关联删除到相关的次要实体:
Person primary = db.People.Find(Id);
if (primary == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
// This line is required to load the related entity
db.Entry(primary).Reference("Secondary").Load();
primary.Secondary = null;
db.SaveChanges();
我必须添加行db.Entry(primary).Reference("Secondary").Load();
才能让它正常工作。我理解这是因为实体框架使用的是延迟加载。但是,我是否可以在Find方法中重写这一点,并通过使用Find方法的热切版本来消除额外的行呢?
发布于 2016-08-22 23:51:31
急切加载是通过Include
方法完成的:
db.People.Include(p => p.Secondary)
例如,后面可以是FirstOrDefault(p => p.Id == id)
。
Find
是一个DbSet
方法,它首先尝试在上下文的缓存中找到请求的实体。只有当在那里找不到实体时,才从数据库中获取该实体。
由于( Find
)这种特殊的行为,Include
和Find
不能混合。当根实体在缓存中找到时,很难定义要做什么,但是要包含的实体不是(或仅部分)。应该从数据库中获取它们吗?这意味着Find
+ Include
总是必须查询数据库中包含的实体,因为它不能依赖本地缓存才能完成。这将违背Find
的宗旨。或者,如果根实体在本地缓存中,那么应该只查找本地缓存中的实体吗?这将使该方法的结果模糊不清。
在ASP.Net MVC (或Web )操作方法中,Find
几乎没有用处,因为大多数情况下,将创建一个新的上下文并从数据库中获取一次实体。换句话说,缓存中没有任何要返回的内容。为了简洁起见,您可能希望使用该方法,但对于数据库往返,其效果与FirstOrDefault()
相同。
发布于 2020-04-26 22:20:53
要回答有关如何使用带有显式加载(从这里开始)的查找方法的原始问题?
using (var context = new BloggingContext())
{
var post = context.Posts.Find(2);
// Load the blog related to a given post.
context.Entry(post).Reference(p => p.Blog).Load();
// Load the blog related to a given post using a string.
context.Entry(post).Reference("Blog").Load();
var blog = context.Blogs.Find(1);
// Load the posts related to a given blog.
context.Entry(blog).Collection(p => p.Posts).Load();
// Load the posts related to a given blog
// using a string to specify the relationship.
context.Entry(blog).Collection("Posts").Load();
}
要添加到@GertArnolds,如果您使用依赖注入,在每个DbContext生活方式中加载一次Scoped
,实质上是:(从这里开始):
每个web请求的容器将只创建一个实例。在ASP.NET Web和ASP.NET MVC应用程序中使用这种生活方式。
然后,DbContext停留了一段时间。
发布于 2016-08-22 13:26:33
或者你可以用
var result = db.Person.Include(c=>c.Secondary).FirstOrDefault(entity=>entity.Id == Id);
对包含中的Linq功能使用using System.Data.Entity;
,否则只需使用字符串“备用”,如:.Include("Secondary")
https://stackoverflow.com/questions/39088847
复制