代码优先EF6未检索内部对象

本文关键字:检索 内部对象 EF6 代码 | 更新日期: 2025-01-25 14:23:47

明显的重复是ef5,这是ef6,但我需要的答案是虚拟的(延迟加载),不存在于明显的重复中

我想我把代码优先的方法搞砸了。。。

最初,我们先从数据库中编写代码,一切都很好,但从链的上游开始,出现了新的需求,所以我们废弃了那个数据库,更新了代码以匹配,然后首先使用代码生成了一个新的数据库。

我们保留了旧的项目,只是更改了我们需要的一切,并清理了代码,从初始代码中删除了所有自动生成的内容(从数据库中首先执行代码),这样我们就可以先对数据库执行正确的代码。

这里的问题是类(我将其简化为两个类,而不是整个代码库)ImageCoordinates包含一个Imagedata对象,但在代码中,当我检索ImageCoordinations时,它会为Imagedata对象返回null。。。

public class ImageCoordinate
{
    [Key]
    public Guid uid { get; set; }
    [StringLength(50)]
    public string coordinates { get; set; }
    public ImageData ImageData { get; set; }
}
public class ImageData
{
    [Key]
    public Guid uid { get; set; }
    [Column("imageData")]
    public byte[] imageData1 { get; set; }
    [StringLength(50)]
    public string fileName { get; set; }
}

dbContext类包含

public class dbContext : DbContext
{
    public dbContext(string connectionString)
        : base(connectionString)
    {
    }
    public virtual DbSet<ImageCoordinate> ImageCoordinates { get; set; }
    public virtual DbSet<ImageData> ImageDatas { get; set; }
}

当检索。。。

var foo = dc.ImageCoordinates.FirstOrDefault(x => x.uid == uid);
foo.ImageData //is null

在数据库端,自动生成的结构。。。。

 uid                                     coordinates    ImageData_uid
AC5712F6-B69B-44FE-A255-3F3227E02802    34,15,158,56    FFE0473D-4CF7-4B26-BE8A-A24FC79B6695

有人能解释一下我在这里做错了什么,阻止系统生成链接并检索图像坐标的所有数据吗?

代码优先EF6未检索内部对象

因此,要么将关联属性声明为virtual以启用延迟加载,要么使用Include在物化点加载关联数据。

public virtual ImageData ImageData { get; set; }

dc.ImageCoordinates
  .Include(ic => ic.ImageData)
  .FirstOrDefault(x => x.uid == uid);

您想要的功能是懒惰加载。它在默认情况下处于启用状态。它必须获取已使用virtual关键字声明的所有子实体。因此,考虑将此属性更改为virtual

public class ImageCoordinate
{
    ...
    public virtual ImageData ImageData { get; set; }
}

或者您可以使用Include来加载查询中声明的子实体。此过程被称为热切加载

dc.ImageCoordinates
  .Include(x=> x.ImageData)
  .FirstOrDefault(x => x.uid == uid);

此外,您可以在上下文构造函数中手动启用Lazy Loading

public MyEntitiesContext() : base("MyEntitiesContext")
{
    this.ContextOptions.LazyLoadingEnabled = true;
    ...
}

如果您希望导航属性是延迟加载的,那么您需要将它们声明为virtual:

public class ImageCoordinate
{
   //...
  public virtual ImageData ImageData { get; set; }
}

在这个链接中,你会找到一个很好的解释,说明如果你想为实体启用延迟加载,并让实体框架在更改发生时跟踪类中的更改,你必须遵守的要求。

仅供参考,EF有三种加载相关实体的方法:懒惰加载、渴望加载和显式加载。最常用的是前两种。