我是 Entity Framework 的新手,正在尝试学习如何使用 Code First 从数据库中加载实体。
我的模型包含一个用户:
public class User
{
public int UserID { get; set; }
[Required]
public string Name { get; set; }
// Navigation Properties
public virtual ICollection<AuditEntry> AuditEntries { get; set; }
}
每个用户都可以有一组审计条目,每个条目都包含一条简单的消息:
public class AuditEntry
{
public int AuditEntryID { get; set; }
[Required]
public string Message { get; set; }
// Navigation Properties
public int UserID { get; set; }
public virtual User User { get; set; }
}
我有一个 DBContext 只公开两个表:
public DbSet<User> Users { get; set; }
public DbSet<AuditEntry> AuditEntries { get; set; }
我想要做的是加载包含消息的 AuditEntry 对象列表以及包含 UserID 和 Name 属性的相关 User 对象。
List<AuditEntry> auditEntries = db.AuditEntries.ToList();
因为我将导航属性标记为虚拟并且我没有禁用延迟加载,所以我得到了一个无限深的对象图(每个 AuditEntry 都有一个 User 对象,其中包含 AuditEntries 的列表,每个都包含一个 User 对象,其中包含 AuditEntries 列表等)
如果我想序列化对象(例如在 Web API 中作为结果发送),这并不好。
我尝试关闭延迟加载(通过从模型中的导航属性中删除虚拟关键字,或者将 this.Configuration.LazyLoadingEnabled = false; 添加到我的 DBContext)。正如预期的那样,这会生成一个包含 User 设置为 null 的 AuditEntry 对象的平面列表。
关闭延迟加载后,我尝试像这样急切加载用户:
var auditentries = db.AuditEntries.Include(a => a.User);
但这会导致与以前相同的深度/循环结果。
如何在不加载反向引用/跟随导航属性回到原始对象并创建循环的情况下加载一层深度(例如,包括用户的 ID 和名称)?