Skip to main content
 首页 » 编程设计

c#之我用 EF 6 实现外键的错误是什么

2024年08月12日46JeffreyZhao

我目前正在学习使用 EF 6 的 ASP.NET MVC 5。现在我坚持使用 Fluent API 声明外键,然后将数据播种到声明的表中。 这是我的代码:

模型:

public class Person 
{ 
    public int Id { get; set; } 
    public ICollection<Anime> DirectedAnimes { get; set; } 
} 
 
public class Anime 
{ 
    public int Id { get; set; } 
    public int DirectorId { get; set; } 
    public Person Director { get; set; } 
} 
 
 
public class AnimeDbContext : DbContext 
{ 
    public DbSet<Person> Persons { get; set; } 
    public DbSet<Anime> Animes { get; set; } 
 
    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
        modelBuilder.Entity<Anime>() 
            .HasRequired(a => a.Director) 
            .WithMany(p => p.DirectedAnimes) 
            .HasForeignKey(p => p.DirectorId); 
        base.OnModelCreating(modelBuilder); 
    } 
} 

播种数据:

public class AnimeInitializer : DropCreateDatabaseAlways<AnimeDbContext> 
{ 
    protected override void Seed(AnimeDbContext context) 
    {    
        var persons = new List<Person> 
        { 
            new Person { Id = 1 }, 
            new Person { Id = 2 } 
        }; 
        var animes = new List<Anime> 
        { 
            new Anime { DirectorId = 1 }, 
            new Anime { DirectorId = 2 } 
        }; 
        persons.ForEach(p => context.Persons.Add(p)); 
        context.SaveChanges(); 
        animes.ForEach(a => context.Animes.Add(a)); 
        context.SaveChanges(); 
    } 
} 

但是当我获取 Anime 对象时,它们期望的是 DirectorId 值,但是它们的 Director 属性是null:

var director = (new AnimeDbContext()).Animes.First().Director; //null 
var directorId = (new AnimeDbContext()).Animes.First().DirectorId; //1 

虽然 Entity Framework 知道外键,因为在 Seed 方法中添加 new Anime {DirectorId = 3} 会导致运行时错误。

我很确定我的错误非常愚蠢,是由于我没有准确地遵循示例造成的,但是我已经为这个问题苦苦挣扎了一段时间,但仍然无法弄清楚。非常感谢您的帮助。

请您参考如下方法:

您的导航属性不是虚拟的,因此不能被 DynamicProxy 覆盖。

改成这样:

public class Person 
{ 
    public int Id { get; set; } 
    public virtual ICollection<Anime> DirectedAnimes { get; set; } 
} 
 
public class Anime 
{ 
    public int Id { get; set; } 
    public int DirectorId { get; set; } 
    public virtual Person Director { get; set; } 
}