非常奇怪的问题,我在许多项目中一直使用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表中的记录确实存在。
答案 0 :(得分:2)
我不确定我完全理解你的问题,因为你在这里玩一些快速和松散的术语。实体框架意义上的动态代理是EF动态创建的类,它们从实际实体类继承并覆盖虚拟引用和导航属性以启用延迟加载。在大多数情况下,这不是你真正需要注意的事情。
始终明确添加导航属性。在任何情况下,实体框架都不会为您添加这些内容。从技术上讲,你所拥有的是Article
类的两个参考属性,就是这样。因此,Entity Framework会创建Article
类的代理,并从查询结果中返回该代理的实例。通过尝试访问某个引用属性(如Image
),可以激活代理类添加的延迟加载逻辑,从而导致向数据库发出新查询以获取该Media
实例。结果将是使用数据库查询结果实例化的对象或null。我不能说为什么你得到一个带有“默认”值的实例化Media
实例。实体框架没有任何内容可以导致这种情况。您必须有一些其他代码干扰实例。
就Media
和Employee
而言,这些类没有导航属性。如果您希望能够访问相关Article
的集合,那么您需要添加以下内容:
public virtual ICollection<Article> Articles { get; set; }