我不确定如何使用代码优先迁移功能。据我了解,如果它不存在,它应该创建我的数据库,并根据迁移文件将其更新为最新模式。但我正在为此苦苦挣扎,因为我总是遇到很多错误,而且我不确定总体上如何正确使用它..
internal class Program
{
private static void Main()
{
EntityFrameworkProfiler.Initialize();
Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Migrations.Configuration>());
using (var context = new MyContext())
{
var exists = context.Database.Exists();
if (!exists)
{
context.Database.Create();
}
var element = context.Dummies.FirstOrDefault();
}
}
}
public class MyContext : DbContext
{
public MyContext()
: base(string.Format(@"DataSource=""{0}""", @"C:\Users\user\Desktop\MyContext.sdf"))
{
}
public DbSet<Dummy> Dummies { get; set; }
}
internal sealed class Configuration : DbMigrationsConfiguration<MyContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(CodeFirstTest.MyContext context)
{
}
}
使用 Entity Framework Profiler 我检查执行了哪些语句。当我在不存在数据库的情况下运行程序时,我得到以下输出:
-- 语句#1 SELECT [GroupBy1].[A1] AS [C1] FROM (SELECT COUNT(1) AS [A1] FROM [__MigrationHistory] AS [Extent1]) AS [GroupBy1]
-- 语句#2 WARN: System.Data.SqlServerCe.SqlCeException (0x80004005): 指定的表不存在。[ __MigrationHistory ] 在 System.Data.SqlServerCe.SqlCeCommand.CompileQueryPlan() 在 System.Data.SqlServerCe.SqlCeCommand.ProcessResults(Int32 hr) 在 System.Data.SqlServerCe.SqlCeCommand.ExecuteCommand(CommandBehavior 行为,字符串方法,ResultSetOptions 选项) 在System.Data.SqlServerCe.SqlCeCommand.ExecuteReader(CommandBehavior 行为) 在 System.Data.SqlServerCe.SqlCeMultiCommand.ExecuteReader(CommandBehavior 行为) 在 System.Data.SqlServerCe.SqlCeMultiCommand.ExecuteDbDataReader(CommandBehavior 行为) 在 HibernatingRhinos.Profiler.Appender.ProfiledDataAccess。 ProfiledCommand.ExecuteDbDataReader(CommandBehavior 行为)
-- 语句#3 SELECT [GroupBy1].[A1] AS [C1] FROM (SELECT COUNT(1) AS [A1] FROM [__MigrationHistory] AS [Extent1]) AS [GroupBy1]
-- 语句#4 WARN: System.Data.SqlServerCe.SqlCeException (0x80004005): 指定的表不存在。[ __MigrationHistory ] 在 System.Data.SqlServerCe.SqlCeCommand.CompileQueryPlan() 在 System.Data.SqlServerCe.SqlCeCommand.ProcessResults(Int32 hr) 在 System.Data.SqlServerCe.SqlCeCommand.ExecuteCommand(CommandBehavior 行为,字符串方法,ResultSetOptions 选项) 在System.Data.SqlServerCe.SqlCeCommand.ExecuteReader(CommandBehavior 行为) 在 System.Data.SqlServerCe.SqlCeMultiCommand.ExecuteReader(CommandBehavior 行为) 在 System.Data.SqlServerCe.SqlCeMultiCommand.ExecuteDbDataReader(CommandBehavior 行为) 在 HibernatingRhinos.Profiler.Appender.ProfiledDataAccess。 ProfiledCommand.ExecuteDbDataReader(CommandBehavior 行为)
-- 语句#5 SELECT [GroupBy1].[A1] AS [C1] FROM (SELECT COUNT(1) AS [A1] FROM [__MigrationHistory] AS [Extent1]) AS [GroupBy1]
-- 语句#6 WARN: System.Data.SqlServerCe.SqlCeException (0x80004005): 指定的表不存在。[ __MigrationHistory ] 在 System.Data.SqlServerCe.SqlCeCommand.CompileQueryPlan() 在 System.Data.SqlServerCe.SqlCeCommand.ProcessResults(Int32 hr) 在 System.Data.SqlServerCe.SqlCeCommand.ExecuteCommand(CommandBehavior 行为,字符串方法,ResultSetOptions 选项) 在System.Data.SqlServerCe.SqlCeCommand.ExecuteReader(CommandBehavior 行为) 在 System.Data.SqlServerCe.SqlCeMultiCommand.ExecuteReader(CommandBehavior 行为) 在 System.Data.SqlServerCe.SqlCeMultiCommand.ExecuteDbDataReader(CommandBehavior 行为) 在 HibernatingRhinos.Profiler.Appender.ProfiledDataAccess。 ProfiledCommand.ExecuteDbDataReader(CommandBehavior 行为)
-- 语句 #7 SELECT [GroupBy1].[A1] AS [C1] FROM (SELECT COUNT(1) AS [A1] FROM [__MigrationHistory] AS [Extent1]) AS [GroupBy1]
-- 语句#8 WARN: System.Data.SqlServerCe.SqlCeException (0x80004005): 指定的表不存在。[ __MigrationHistory ] 在 System.Data.SqlServerCe.SqlCeCommand.CompileQueryPlan() 在 System.Data.SqlServerCe.SqlCeCommand.ProcessResults(Int32 hr) 在 System.Data.SqlServerCe.SqlCeCommand.ExecuteCommand(CommandBehavior 行为,字符串方法,ResultSetOptions 选项) 在System.Data.SqlServerCe.SqlCeCommand.ExecuteReader(CommandBehavior 行为) 在 System.Data.SqlServerCe.SqlCeMultiCommand.ExecuteReader(CommandBehavior 行为) 在 System.Data.SqlServerCe.SqlCeMultiCommand.ExecuteDbDataReader(CommandBehavior 行为) 在 HibernatingRhinos.Profiler.Appender.ProfiledDataAccess。 ProfiledCommand.ExecuteDbDataReader(CommandBehavior 行为)
-- 语句 #9 以隔离级别开始事务:可序列化
-- 语句 #10 CREATE TABLE [Dummies] ([Name] nvarchar NOT NULL, CONSTRAINT [PK_Dummies] PRIMARY KEY ([Name]) )
-- 语句 #11 CREATE TABLE [ MigrationHistory] ( [MigrationId] nvarchar NOT NULL, [CreatedOn] [datetime] NOT NULL, [Model] [image] NOT NULL, [ProductVersion] nvarchar NOT NULL, CONSTRAINT [PK _MigrationHistory] PRIMARY KEY ([MigrationId]) )
-- 语句 #12 INSERT INTO [__MigrationHistory] ([MigrationId], [CreatedOn], [Model], [ProductVersion]) VALUES ('201207261524579_InitialCreate', '2012-07-26T15:24:58.523', 0x1F8B080 , '4.3. 1')
-- 语句#13 提交事务
-- 语句 #14 SELECT TOP (1) [c].[Name] AS [Name] FROM [Dummies] AS [c]
如您所见,它在实际创建数据库之前尝试访问数据库四次。这似乎不对。当我使用现有数据库启动应用程序时,它会在执行任何实际查询之前查询数据库 7 次。请注意,这发生在context.Database.Create()
,而不是.Exists()
。
我的配置的种子方法也从未被调用,但构造函数是。
这一切似乎都非常错误和令人困惑。我希望有人能告诉我为什么错误在一开始经常发生,为什么我的种子方法根本没有被调用。
我正在使用 SqlServer compact 和 Entity Framework 的最新稳定版本。
包 id="EntityFramework" 版本="4.3.1" targetFramework="net40"
包 id="Microsoft.SqlServer.Compact" 版本="4.0.8854.2" targetFramework="net40"