【问题标题】:Navigation property is empty导航属性为空
【发布时间】:2015-01-12 15:10:10
【问题描述】:

非常奇怪的问题,我在很多项目中都使用 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);

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

  • 图像导航属性为空。它不是 null,但它的所有属性都有默认值(0、null 等...)
  • Article 对象具有动态代理,但导航属性 Image 和Employees 没有。如果我没记错的话,导航属性默认应该被动态代理包装。
  • 需要注意的重要一点是,Employee 导航属性的所有属性都已正确加载。这很好,但是上面没有动态代理。

过去 2 小时我一直在尝试解决此问题,但我没有办法了。

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

谢谢!

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

【问题讨论】:

    标签: c# asp.net-mvc entity-framework ef-code-first asp.net-mvc-5


    【解决方案1】:

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

    始终显式添加导航属性。在任何情况下,实体框架都不会为您添加这些。从技术上讲,您拥有的是 Article 类上的两个参考属性,仅此而已。因此,Entity Framework 创建 Article 类的代理并从查询结果中返回该代理的实例。通过尝试访问您的参考属性之一,例如Image,您激活了代理类添加的延迟加载逻辑,导致向数据库发出新查询以获取该Media 实例。结果将是使用数据库查询结果实例化的对象或 null。我不能说为什么你会得到一个具有“默认”值的实例化 Media 实例。没有任何关于实体框架的东西会导致这种情况。您必须有其他代码干扰该实例。

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

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

    【讨论】:

    • 非常感谢您抽出宝贵时间回复我的问题。谢谢,对我来说,文章和媒体是具有 1 到 0 关系的导航属性,在您的示例中,文章是 1 到 n 关系的导航属性。感谢您对代理的解释,但我实际上知道这一点。我指出没有围绕这些导航属性创建代理来帮助解决问题,因为 IIRC,通常应该是这种情况。
    • 这就是我的意思。没有创建代理,因为这些特定的类没有任何引用或导航属性。如果没有什么可以延迟加载,那么 Entity Framework 不需要创建代理。
    • 哦,我现在明白了,谢谢!我将继续查看我的代码,看看是否有关于 Media 属性为 null 的解释,但我真的不知道是什么原因造成的。
    • 刚刚发现,如你所说,与EF无关。我每次都在 Article 的构造函数中分配一个新的 Media ...但是现在我想知道 EF 何时将检索到的对象的属性与 db 的值一起分配。也许它会跳过在构造函数中手动分配的属性?感谢您的帮助,有别人的观点很令人耳目一新。
    猜你喜欢
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 2022-12-05
    相关资源
    最近更新 更多