如何使用Entity Framework设置正确的导航属性?

时间:2014-06-11 16:55:39

标签: c# entity-framework

我正在尝试创建一个.NET MVC网站,我在通过实体框架加载和保存数据库中的相关表时遇到了一些麻烦。

1)当我尝试从一个表访问一个相关的实体时,我的导航属性似乎是空的,即使它不应该?

public class Table1 {
    public int Table1ID { get; set; }
    public string Name { get; set; }
    [ForeignKey("Table2")]
    public int Table2ID { get; set; }
    [ForeignKey("Table2ID")]
    public virtual Table2 Table2 { get; set; }
}

public class Table2 {
    public int Table2ID { get; set; }
    public string Name { get; set; }
    public virtual Table1 Table1 { get; set; }
}

我在我的EF上下文类中有这样的映射:

public class EFDbContext : DbContext {
    public DbSet<Table1> Table1 { get; set; }
    public DbSet<Table2> Table2 { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Entity<Table2>().HasOptional(u => u.Table1).WithRequired().WillCascadeOnDelete(true);
    }
}

在我的控制器中,我获取想要的Table2实例并将其发送到我的视图:

public ViewResult Edit(int productId) {
    Table2 Table2Instance = repository.Table2.FirstOrDefault(p => p.Table2ID == productId);
    return View(Table2Instance);
}

在我看来,我需要做一个动作,具体取决于Table2Instance是否与Table1有关系,我试图这样做:

@model Entities.Table2

@if (Model.Table1 == null && Model.Table2ID != 0){
    //Do this
}else if (Model.Table1 != null && Model.Table2ID != 0) {
    //Do that
}

但似乎我的导航属性无法正常工作,因为即使数据库有关系,它也总是将Model.Table1显示为null。 我该如何设置这个导航属性?

2)当我尝试使用context.Table1.Add(Table1Instance)然后使用context.SaveChanges()保存新的Table1属性时,我得到一个错误,因为它每次尝试将Table1ID保存为0并且不递增?

2 个答案:

答案 0 :(得分:2)

默认情况下不会读取相关的导航属性。要阅读它们,您可以使用:

  • 延迟加载(即启用LazyLoading时访问该属性)
  • 急切加载(即使用Include
  • 显式加载(它有点复杂)

在您的情况下,更合适的解决方案是急切加载,这样做:

Table2 Table2Instance = repository
  .Table2
  .Include(t2 => t2.Table1) // add this to your query
  .FirstOrDefault(p => p.Table2ID == productId);

关于第二个问题,您应该显示更多代码。您必须意识到,在分层应用程序中,当您的实体离开DbContext时,您必须将其附加回来,并在调用SaveChanges之前设置实体状态。

答案 1 :(得分:0)

  

因为它每次尝试将Table1ID保存为0并且不会递增?

您需要将列设置为标识列:

modelBuilder.Entity<Table2>()
  .HasOptional(u => u.Table1)
  .WithRequired()
  .WillCascadeOnDelete(true);

modelBuilder.Entity<Table2>()
  .Property(x => x.Table2ID )
  .StoreGeneratedPattern = StoreGeneratedPattern.Identity;