gpt4 book ai didi

entity-framework - SQL Server 2005 的代码优先?

转载 作者:行者123 更新时间:2023-12-02 02:17:57 37 4
gpt4 key购买 nike

我的开发数据库是 2008 R2,这是 Code First 使用 DropCreateIfModelChanges 生成本地数据库的地方。

我部署到生产环境的方法是从本地数据库生成脚本,包括数据并在生产环境中运行。这将创建所有表,包括 EdmMetadata 表并使用哈希填充它。

作品:在不同的 2008 R2 实例中运行脚本,更改实体模型的连接字符串以指向此生产实例,运行应用程序。

无效:在不同的 2005 实例中运行脚本,更改实体模型的连接字符串以指向此生产实例,运行应用程序。我收到一条错误消息,指示模型已更改。

我认为这不起作用,因为数据库兼容版本是散列的一部分。因此在生产中它生成一个散列并将其与存储在 EdmMetadata 表中的散列进行比较。新哈希值不同,因为它是针对 2005 数据库生成的。

我猜如果我在本地生成 2005 数据库并将其部署到 2005 生产实例,我就不会遇到这个问题。但是我没有安装 2005,并且不想要求所有开发人员都必须安装它,因为 2008 已经支持 2005 兼容模式。

如何强制 EF 在 2005 兼容模式下生成数据库?

最佳答案

如果唯一的问题是模型兼容性检查,那么您可以在生产环境中运行时为您的上下文禁用数据库初始化器,因为您大概不需要初始化数据库。您可以像这样在代码中执行此操作:

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/ .

您也可以尝试只更新到不再使用 EdmMetadata 表的 EF 4.3——而是使用 __MigrationHistory 表。这以不同的方式检查模型兼容性。如果 Code First 为 2005 年生成的数据库与为 2008 年生成的数据库不同,它可能仍会标记差异,这种情况偶尔会发生。

您可以在您的开发箱上安装 SQL Server 2005 Express。它是免费的,并且会更好地匹配您的生产环境。

最后,如果以上方法都不起作用并且您需要强制 Code First 生成 2005 模型/数据库,那么您可以这样做,但这意味着使用较低级别的构建 block 。首先,您需要自己创建 DbModelBuilder 并为每个在上下文中声明了 DbSet 的实体类型调用 Entity:

var modelBuilder = new DbModelBuilder();
modelBuilder.Entity<User>();
modelBuilder.Entity<Blog>();

您可以在此处进行其他流畅的配置或正常使用数据注释。 OnModelCreating 不会被调用,所以不要在那里进行流畅的调用——而是将它们移到这里。

配置 DbModelBuilder 后,您需要构建和编译以获得可传递给 DbContext 的编译模型。在此阶段,您可以将“2005”作为提供者 list 标记传递。

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; }
}

如果需要,还有其他构造函数重载用于传递名称或连接字符串。

关于entity-framework - SQL Server 2005 的代码优先?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9608163/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com