如果唯一的问题是模型兼容性检查,那么在生产环境中运行时,您可以禁用上下文的数据库初始化器,因为您可能不需要初始化数据库。您可以通过以下代码来实现这一点:
Database.SetInitializer<MyContext>(null);
但是在生产应用中,最好在app.config/web.config中进行配置,如下所示:
<entityFramework>
<contexts>
<context type="MyNamespace.MyContext, MyAssembly" disableDatabaseInitialization="true" />
</contexts>
</entityFramework>
您需要更新到EF 4.3才能使用这个语法--请参见
http://blogs.msdn.com/b/adonet/archive/2012/01/12/ef-4-3-configuration-file-settings.aspx。在EF 4.1中也有一种方法:请参见
http://blog.oneunicorn.com/2011/03/31/configuring-database-initializers-in-a-config-file/。
您也可以尝试直接升级到EF 4.3,它不再使用EdmMetadata表,而是使用__MigrationHistory表。这种方式以不同的方式检查模型兼容性。如果Code First为2005生成的数据库与为2008生成的数据库不同,它仍然可能会标记出差异,这种情况偶尔会发生。
您可以在开发机上安装SQL Server 2005 Express。它是免费的,可以更好地匹配您的生产环境。
最后,如果以上方法都不起作用,你需要强制Code First生成一个2005的模型/数据库,那么你可以这样做,但这意味着使用更低级别的构建块。首先,你需要自己创建DbModelBuilder并为上下文中声明了DbSet的每个实体类型调用Entity方法:
var modelBuilder = new DbModelBuilder();
modelBuilder.Entity<User>();
modelBuilder.Entity<Blog>();
您可以在此处进行其他流畅的配置,或像往常一样使用数据注释。不会调用OnModelCreating,所以不要在那里放置流畅的调用-而是将它们移到这里。
一旦您有一个配置好的DbModelBuilder,您需要构建和编译才能获得一个编译后的模型,该模型可以传递给DbContext。在这个阶段,您可以将“2005”作为提供程序清单标记传递进去。
var compiledModel = modelBuilder
.Build(new DbProviderInfo("System.Data.SqlClient", "2005"))
.Compile();
现在你应该将这个已编译的模型缓存到你的应用程序域中,这样你只需要构建和编译一次。 (通常情况下,DbContext 在构建模型时会自动进行缓存,但如果你需要自己构建模型,那么你也需要自己进行缓存。)
最后,你需要每次使用时将编译好的模型传递给上下文的一个构造函数,并让该构造函数将模型传递给基类构造函数。
public class MyContext : DbContext
{
public MyContext(DbCompiledModel model)
: base(model)
{
}
public DbSet<User> Users { get; set; }
public DbSet<Blog> Blogs { get; set; }
}
如果需要的话,还有其他构造函数重载可以传递名称或连接字符串。