【问题标题】:Can I change the default schema name in entity framework 4.3 code-first?我可以在实体框架 4.3 代码优先中更改默认架构名称吗?
【发布时间】:2012-03-22 16:51:51
【问题描述】:

目前,我正在将我的应用程序部署到共享托管环境中,并且代码优先的迁移一直运行良好,除了一个小问题。每次我想推送站点时,我都必须使用“Update-Database -script”选项,因为我必须在每个表名前面加上[dbo],因为默认情况下,共享主机会创建一个与数据库用户名。

如果我登录到我的共享主机并创建一个数据库,那么我必须创建一个用户。如果我将该用户命名为 admin,那么在以 admin 身份登录时代码首先创建的表看起来类似于“[admin].[BlogPosts]”。当应用程序运行时,所有表都已创建,但我得到一个 EF 异常,因为它说“[dbo].[BlogPosts]”无效。如果我将表的架构名称重命名为“[dbo]”而不是修复它的“[admin]”。

为了解决这个问题,我必须生成一个手动执行的迁移脚本,并在所有表名前添加“[dbo]”,因为该脚本仅按表名引用表,而不是通过模式和名称引用表.

有没有简单的方法来解决这个问题?如果我所要做的就是发布应用程序并且一切正常,那就太好了。如果不是因为架构名称的差异,那将是一键部署,一切都会很美好。

【问题讨论】:

  • 您可以尝试为您的管理员帐户运行ALTER USER,并将dbo 指定为默认架构。 (这并不能回答所提出的问题,但可能是一个解决方案)
  • 我实际上比手动指定表映射更喜欢这个解决方案。
  • 这个问题的标题是“我可以在实体框架4.3代码优先中更改默认模式名称吗?”接受的答案是我认为最能回答这个问题的答案。

标签: c# sql entity-framework entity-framework-4 ef-code-first


【解决方案1】:

您可以使用ToTable 方法来指定架构名称。如果不指定架构名称,EF 将按照约定使用dbo

public class MyContext
{
    private string schemaName = "Foo";

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
         modelBuilder.Entity<MyEntity>().ToTable("MyTable", schemaName);
    } 
}

【讨论】:

  • 这是一个不错的解决方案。很糟糕,我必须将每个实体显式映射到一个表。我有很多。我希望我可以指定一个默认模式名称。或者我希望如果 EF 决定使用“dbo”,那么它应该在运行 SQL 时在表名前显式添加“dbo”。
  • @AlexFord 是的。希望有一个添加自定义约定的工具。
  • 我接受了这个,但我没有使用它。这确实是一个解决方案,但我选择了简单的选项,只是使用 Damien_The_Unbeliever 的选项 ALTER USER admin WITH DEFAULT_SCHEMA=dbo 更改数据库用户的默认模式。现在,默认情况下将在 dbo 下创建未指定架构的新表。
  • 谢谢 Alex Ford,在研究了 1000 页并尝试了 10 种不同的解决方案后,我终于找到了您的评论:D 这是唯一对我有用的,也是最好的解决方案。
  • @JBeckton 不是在这个问题的时候你不能。 EF 4.3 代码优先是一个非常早期的代码优先实现。此问题与最新版本的 EF 无关。
【解决方案2】:

对于数据库优先的实现,这很容易。打开edmx文件,右键->属性,设置默认数据库架构。

对于代码优先,这篇文章似乎最有前途:https://web.archive.org/web/20150210181840/http://devproconnections.com/entity-framework/working-schema-names-entity-framework-code-first-design

【讨论】:

  • 这个问题与最新版本的 EF 代码优先无关。这只是 EF 4.3 代码优先中的问题。相信5及以上不再有这个问题了。
【解决方案3】:

对于那些使用 Entity Framework 6 的人,只需使用 HasDefaultSchema 方法:

public class Contexto : DbContext
{
    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("MyDefaultDbSchema");
    }
}

【讨论】:

  • 耶!我很高兴他们终于添加了原生支持。
  • 这也适用于 SQLCE,如果你想完全放弃模式。只需使用String.Empty
  • 对于那些想知道的人,是的,您只需添加这一行代码,只要您没有在表上明确设置模式,当您执行“添加迁移”,然后是“更新数据库”。
  • 我对标记的答案有评论...有没有办法获取默认架构的值?没有模型构建器?
  • 是的,虽然我忘记了这就是我再次搜索的原因,但这是正确的答案,因为它甚至将迁移表移动到了这个模式......
【解决方案4】:

我想补充一下,因为这是针对C#的,我在下面写了一个针对VB的

Public Class ClientDbContext
Inherits DbContext
Public Property Clients As DbSet(Of Client)

Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
    modelBuilder.HasDefaultSchema("dbo")
End Sub
End Class

【讨论】:

    【解决方案5】:

    EF Code first中,默认情况下,一切都基于SQL Server 中的管理访问“DBO-Schema”的用户访问设置。但是,如果特定用户被定义为使用共享主机中常见的数据库,那么将不再有 Dbo 管理访问权限。这次我们的表名是dbo.tableName,比如someUser.tableName,这点不准确导致程序无法运行。修改和显式分配连接到数据库的用户。 如果使用元数据,应使用以下方法

    [Table("MyTableName", Schema="MySchemaName")]
    public class MyClassName
    {
     //Other Lines...
    }
    

    (是否Fluent API可自定义如下:)

    modelBuilder.Entity<Blog>().ToTable("MyTableName", schemaName:"MySchemaName");
    

    请注意以下事项:

    很好的学习参考: http://www.c-sharpcorner.com/article/fluent-api-in-code-first-approach/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多