我正在尝试创建一个.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并且不递增?
答案 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;