我正在学习MVC,我理解如何创建单个模型类,然后创建单个上下文类,然后基于模型/上下文组合创建控制器和视图,并将模型提交到数据库使用代码优先。
现在我想把第二个Model(以及表格)带入混音中。我最初尝试创建第二个上下文类,然后是第二个模型类,然后以相同的方式创建控制器和视图。结果我发现我一次只能将一个模型提交到数据库。每当我在一个模型上启用自动迁移,然后在包管理器中运行Update-Database
命令时,另一个表从我的数据库中消失,另一个模型的添加/删除/编辑/查看功能中断。
当然,您必须能够使用此技术来管理多个表吗?我的问题是,如果我有两个模型类,如下所示:
[Table("TableOne")]
public class ModelOne
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Foo { get; set; }
}
[Table("TableTwo")]
public class ModelTwo
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Bar { get; set; }
}
如果我想同时使用两者,我的Context类需要看起来是什么样的?我的想法是试试这个:
public class FooBar : DbContext
{
public FooBar()
: base("DefaultConnection")
{
}
public DbSet<ModelOne> TableOne { get; set; }
public DbSet<ModelTwo> TableTwo { get; set; }
}
然后在添加控制器向导中,我可以使用模板下拉列表中的实体框架选择具有读/写操作和视图的MVC控制器模型类下拉列表的> ModelOne ,以及来自数据上下文类下拉列表中的 FooBar 模型,以及与第二个模型的模型类下拉列表中的 ModelTwo 相同的选项,一切都会按预期工作,但每当我尝试创建第一个模型时控制器基于模型一,我得到这个错误:
生成FooBar时出错。尝试重建项目。
我尝试过重建我的项目,但我得到了同样的错误,所以很明显我做错了。我做错了什么,我怎么需要修改我的FooBar上下文类来使事情发挥作用,假设它是我的FooBar上下文类错了?
答案 0 :(得分:2)
通常,上下文类和模型类之间不会有1对1。所有相关模型都进入一个上下文。例如,我的应用程序中每个区域通常有一个上下文,但如果您不使用区域,您仍然可以在单个上下文中逻辑地对模型进行分组。
问题出在哪里是有多个上下文。 EF只喜欢迁移一个上下文。如果没有迁移,您可以通过在上下文类中手动指定它来轻松获取所有上下文类以使用相同的数据库。
public class MyContext: DbContext
{
public MyContext()
: base("name=MyConnectionName")
{
}
}
如果每个上下文都是这样定义的,它们都将使用命名连接字符串指向的相同DB。
就进行迁移而言,编程实体框架:DbContext 的作者Julie Lerman(以及几乎所有相关的EF书籍)都有一个利用通用基础的解决方案class(编辑:实际上Julie将模式归因于EF团队的Arthur Vickers):
public class BaseContext<TContext> : DbContext
where TContext : DbContext
{
static BaseContext()
{
Database.SetInitializer<TContext>(null);
}
protected BaseContext()
: base("name=breakaway")
{
}
}
然后,您将从BaseContext
继承每个单独的上下文:
public class TripPlanningContext : BaseContext<TripPlanningContext>
public class SalesContext : BaseContext<SalesContext>
相关部分从上述书籍的第231页开始。
<强>更新强>
其实我欺骗了你。 Julie提供的模式只是让它们更容易共享同一个数据库。要仅针对一个上下文问题进行迁移,您必须作弊并基本上创建一个包含其中所有内容的大型上下文,然后仅用于数据库初始化/迁移。对于代码中的其他内容,您将使用其他更具体的上下文。