我正在使用MVC5& EF6。我正在做代码优先的方法。我有一些表需要使用迁移(工作)和一些我需要在现有数据库表中使用的表生成。
在DbContext类中我有
'new table that is created in the DB (works)
public DbSet<Subscription> Subscriptions { get; set; }
public DbSet<Memeber> Members { get; set; }
'existing table.
public DbSet<CodeTable> CodeTable { get; set; }
配置 - (迁移文件夹)中的
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
现在它做了什么,它创建了一个名为CodeTable s
的新表更新 - 数据库-Verbose -Force(没有做任何事情)
使用StartUp项目&#39;测试&#39;。
使用NuGet项目&#39;测试&#39;
指定&#39; -Verbose&#39;用于查看应用于目标数据库的SQL语句的标志
目标数据库是:&#39; TESTDB&#39; (DataSource:10.10.50.89,Provider:
System.Data.SqlClient,Origin:Configuration)。
没有待定的显式迁移
运行种子方法。
然后运行应用程序,我得到例外 System.Data.SqlClient.SqlException(0x80131904):无效的对象名称&#39; dbo.Members&#39;。在System.Data.SqlClient.SqlConnection.OnError(SqlException异常
因为找不到表格。表格未生成。
如果找不到表,我怎么知道呢?创造它吗?
我注意到我删除了__MigrationHistory然后运行Update-Database。然后它抱怨我存在的其他表格
已有一个名为&#39; Subscriptions&#39;在数据库中。
它只有在我删除所有表格时才有效。但这似乎很愚蠢,删除所有表格。我希望还有另一种方法。
答案 0 :(得分:1)
要首先在现有数据库中使用代码,您需要做两件事:1)指定连接字符串; 2)关闭数据库初始化策略。使用以下上下文示例可以实现这两件事:
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext()
: base("ConnectionStringName")
{
Database.SetInitializer<ApplicationDbContext>(null);
}
// DbSets here
}
现在,按照惯例,实体框架假定您的表名是实体类名的复数形式。如果表名不是复数和/或它与实体类名不同,那么您可以使用Table
属性来准确指定它应该是什么:
[Table("foo_table")]
public class Foo
{
// properties
}
同样,如果您的列名称与您的属性名称不匹配,则可以使用Column
属性指定这些名称:
[Column("strFoo")]
public string Foo { get; set; }
<强>更新强>
在第一次阅读时,我并未注意到您尝试将现有表格与代码首先生成的表格进行混合和匹配这一事实。你不能做这个。由于使用现有数据库/现有表需要禁用初始化策略,因此该数据库中的所有表都必须存在,或者Entity Framework必须生成所有表。你不能半途而废。
如果你需要利用一些现有的表并让EF创建一些,你需要两个数据库和两个上下文,一个是EF首先通过代码生成所有内容,另一个是初始化策略关闭,你负责对于数据库和表。重要的是,这意味着你可以不混合和匹配这些。您的所有代码第一个实体都不能通过导航属性引用任何现有数据库实体,或者它们将隐式添加到代码第一个上下文中,EF将生成表格。
您可以做的最好的事情是拥有一个包含相关实体ID的常规属性,然后手动使用此ID从现有数据库上下文中查找实体。换句话说,它不会是一个真正的外键,你将无法利用延迟加载等。
答案 1 :(得分:0)
我以不同的方式进行操作-我创建了一个我将需要的所有表的大型上下文-并对该上下文进行了迁移/数据库更新。然后创建几个“只读”上下文-就我称为Database.SetInitializer(null)
而言-意味着它们将不会进行迁移等-并仅在其中添加必要的DbSet
。这样我就可以准确地实现您所描述的内容。