C# 我对IsLoaded的理解正确吗?
下面是一些代码以及我基于在LINQPad中玩游戏的假设。是否有人可以确认这就是延迟加载的工作方式,或者提供任何额外的细节/链接,以便我了解它在后端的工作方式?提前谢谢C# 我对IsLoaded的理解正确吗?,c#,.net,entity-framework,ef-code-first,change-tracking,C#,.net,Entity Framework,Ef Code First,Change Tracking,下面是一些代码以及我基于在LINQPad中玩游戏的假设。是否有人可以确认这就是延迟加载的工作方式,或者提供任何额外的细节/链接,以便我了解它在后端的工作方式?提前谢谢 // Step 1. var record = context.MyTable.First(); // Step 2. var foreignKey = ForeignKeyTable.Where(x => x.Id == record.ForeignKeyId).Single(); // Step 3. var ent
// Step 1.
var record = context.MyTable.First();
// Step 2.
var foreignKey = ForeignKeyTable.Where(x => x.Id == record.ForeignKeyId).Single();
// Step 3.
var entry = context.Entry(record);
// Step 4.
trace(entry.Reference(x => x.ForeignKey).IsLoaded);
// Step 5.
trace(record.ForeignKey.SomeProperty);
record
的外键属性的记录,而不使用像record.ForeignKey
这样的延迟加载来检索它(查询数据库)记录
实体的详细信息true
。我猜IsLoaded不知道record.ForeignKey
当前是否有值,但知道record.ForeignKey
已在上下文中根据其对record.ForeignKeyId
的了解和已建立的关系进行跟踪IsLoaded
在4中返回true。它知道它已经在跟踪foreignKey
对象,因此它知道它不必进行延迟加载var record = context.MyTable.First();
var foreignKey = new ForeignKey() { Id = record.ForeignKeyId, SomeProperty = 5 };
context.ForeignKeyTable.Attach(foreignKey);
var entry = context.Entry(record);
// Returns false.
trace(entry.Reference(x => x.ForeignKey).IsLoaded);
// Doesn't query for ForeignKey, so it must know it's `loaded` somehow, and
// gets SomeProperty from my new foreignKey object. What???
trace(record.ForeignKey.SomeProperty);
记录
,其中有一个外键指向ForeignKeyTable
。上下文知道这个值。(顺便说一句,您是否在模型中公开了外键并不重要。它将始终被加载,模型中也没有FK属性。您可以在查看SQL查询时看到这一点。)
在这两种情况下,您都会在上下文之后附加一个ForeignKey
实体,该实体的主键为上下文已经知道的record.ForeignKeyId
。因此,EF将把导航属性record.ForeignKey
设置到此附加的ForeignKey
实体
显然,IsLoaded
不会告诉您实体是否附加到上下文,因为在这两个示例中,实体都附加了,但一个返回true
,另一个返回false
。它也不会告诉您,record.ForeignKeyId
是否引用实体,因为在两个示例中都是这样
它显然只告诉您实体实际上是从数据库加载的(而不仅仅是手动附加的)(Intellisense也说是关于IsLoaded
)。这是第一个和第二个示例之间的唯一区别
而且,延迟加载似乎不仅仅由IsLoaded
标志控制。如果将导航属性的实体附加到上下文,则不会再发生延迟加载,尽管IsLoaded
为false
如果第二个代码段中的最后一行实际触发延迟加载,会发生什么情况?正在加载的
ForeignKey
对象必须与您已附加的ForeignKey
对象具有相同的键(因为记录
将此值作为FK属性ForeignKeyId
)。但是,由于不能将具有相同密钥的两个对象附加到上下文,因此它必须是同一个对象。但是不需要加载它,因为这样的对象已经在内存中并已附加。我知道,如果使用Include,它将与外键一起加载记录。我更想知道它是如何知道它已经在步骤4中加载的。我在应用程序中运行了类似的测试,步骤4返回false。相当于foreignKey
的加载方式不会创建对象代理,因此我想知道它是否与此有关。它知道加载它是因为它附加到对象上下文。尝试一些在#2中Where子句之前调用AsNoTracking()的示例。你
// Step 1.
var record = context.MyTable.First();
// Step 2.
var foreignKey = ForeignKeyTable.Where(x => x.Id == record.ForeignKeyId).Single();
// Step 3.
var entry = context.Entry(record);
// Step 4.
trace(entry.Reference(x => x.ForeignKey).IsLoaded);
// Step 5.
trace(record.ForeignKey.SomeProperty);