导航 属性 为空

Navigation property is empty

非常奇怪的问题,我一直在很多项目中使用 EF + Code First,但我无法弄清楚这里发生了什么。

我有以下实体:

public class Article
{
    public int ID { get; set; }
    public string Title { get; set; }
    public virtual Media Image{ get; set; }
    public virtual Employee Author {get; set;}
    public MyEnum EnumValue {get; set;}
    public enum MyEnum {Value1, Value2}
}

public class Media
{
    public int ID {get; set;}
    public double Length { get; set; }
    public string ContentType { get; set; }
    public byte[] Content { get; set; }
}

public class Employee
{
    public int ID {get; set;}
    public string Name{get; set;}
    public string Email{get; set;}
}

使用以下 DbContext :

public class MyContext : DbContext
    {
    public MyContext() : base("ConnectionString")
    {
        this.Configuration.LazyLoadingEnabled = true;
        this.Configuration.ProxyCreationEnabled = true;
    }

    public DbSet<Article> Articles { get; set; }
    public DbSet<Employee> Employees { get; set; }
    public DbSet<Media> Medias { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Article>().HasRequired(x => x.Image);
        modelBuilder.Entity<Article>().HasOptional(x => x.Author);
    }
}

这里没什么特别的,但是每当我检索文章时,例如:

var article = _db.Articles.FirstOrDefault(x => x.ID == id);

我有两个问题这是我的问题:

过去 2 小时我一直在尝试解决此问题,但我 运行 完全搞不懂。

如果有任何提示/帮助,我将不胜感激,

谢谢!

更新:我查过数据库,外键没问题,Images table中的记录确实存在。

我不确定我是否完全理解你的问题,因为你在这里对术语的处理有点松散。在 Entity Framework 的意义上,动态代理是 EF 动态创建的 classes,它们继承自实际实体 classes 并覆盖虚拟引用和导航属性以启用延迟加载。在大多数情况下,这不是您真正需要注意的事情。

始终明确添加导航属性。 Entity Framework 在任何情况下都不会为您添加这些。从技术上讲,您拥有的是 Article class 上的两个参考属性,仅此而已。结果,Entity Framework 根据您的查询结果创建 Article class 的代理和 returns 该代理的实例。通过尝试访问您的引用属性之一,例如 Image,您激活了代理 class 添加的延迟加载逻辑,导致向数据库发出新查询以获取 Media 实例。结果要么是用数据库查询结果实例化的对象,要么是 null。我不能说为什么你会得到一个 Media 实例化 "default" 值。 Entity Framework 不会导致这种情况。您必须有一些其他代码干扰实例。

MediaEmployee 而言,这些 class 没有导航属性。如果您希望能够访问相关 Article 的集合,那么您需要添加如下内容:

public virtual ICollection<Article> Articles { get; set; }