我有一个带有 SQL 数据库的 .Net Core 3.1 应用程序。我使用延迟加载代理自动从相关表中检索数据。基本上,我有一个表,它通过一对多或一对一关系引用一些其他实体。事实是,大多数情况下,每个关系都正常,每个实体都已加载,我可以读取它的属性(例如名称字段)。
但是,在非常特殊的情况下,这些实体不会加载,尽管关系 Id 存在。看起来像这样:
模型是这样的:
public partial class Delegation
{
public Guid Id { get; set; }
public int UserFrom { get; set; }
public int UserTo { get; set; }
public virtual User UserFromNavigation { get; set; }
public virtual User UserToNavigation { get; set; }
}
数据库上下文中的初始化:
public virtual DbSet<Delegation> Delegations { get; set; }
...
modelBuilder.Entity<Delegation>(entity =>
{
entity.Property(e => e.Id).ValueGeneratedNever();
entity.HasOne(d => d.UserFromNavigation)
.WithMany(p => p.DelegationsUserFromNavigation)
.HasForeignKey(d => d.UserFrom)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Delegations_Users_From");
entity.HasOne(d => d.UserToNavigation)
.WithMany(p => p.DelegationsUserToNavigation)
.HasForeignKey(d => d.UserTo)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Delegations_Users_To");
});
这个具体示例只是众多示例之一,其他模型中也没有加载其他实体的虚拟 ICollections。
这里,在调试屏幕截图中,UserTo 是 OK,但 UserFrom 是 NULL。
通过 Id 手动搜索实体并检索其属性是可行的,但它会使代码变得更加脏。
有什么方法可以强制 EF 加载那些丢失的实体,还是我在这里犯了一个错误?这种行为看起来真的很随机。
确保您的 DbContext 启用了延迟加载。在 Entity Framework Core 中,默认情况下不启用延迟加载,需要在 Startup 文件或 OnConfiguring 方法中显式启用。
optionsBuilder.UseLazyLoadingProxies();
或者,您可以使用 Include 方法在查询数据时显式加载导航属性,而不是依赖延迟加载:
var data = rmscontext.Delegations
.Include(d => d.UserFromNavigation)
.Include(d => d.UserToNavigation)
.FirstOrDefault(d => d.Id == id);