C# 我可以先更改EntityFramework4.3代码中的默认模式名称吗?

C# 我可以先更改EntityFramework4.3代码中的默认模式名称吗?,c#,sql,entity-framework,entity-framework-4,ef-code-first,C#,Sql,Entity Framework,Entity Framework 4,Ef Code First,目前,我正在将我的应用程序部署到一个共享托管环境中,代码优先和迁移一直运行良好,只是有一个小问题。每次我想要推送站点时,我都必须使用“更新数据库-脚本”选项,因为我必须在每个表名前面加上[dbo],因为默认情况下共享主机会创建一个与数据库用户名相同的默认模式名 如果我登录到共享主机并创建数据库,那么我必须创建一个用户。如果我将该用户命名为admin,那么代码在以admin身份登录时首先创建的表类似于“[admin].[BlogPosts]”。当应用程序运行时,所有的表都被创建了,但是我得到了一个

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

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

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


有没有一个简单的方法来解决这个问题?如果我所要做的就是发布应用程序,然后一切正常,那就太好了。如果没有架构名称差异,那么只需单击一下部署,一切都会很好。

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

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

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
         modelBuilder.Entity<MyEntity>().ToTable("MyTable", schemaName);
    } 
}
公共类MyContext
{
私有字符串schemaName=“Foo”;
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity().ToTable(“MyTable”,schemaName);
} 
}

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


对于代码优先,本文似乎最有希望:

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

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

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("MyDefaultDbSchema");
    }
}
公共类Contexto:DbContext
{
公共数据库集用户{get;set;}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
hasdaultschema(“MyDefaultDbSchema”);
}
}

我想补充一点,因为这是为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

默认情况下,在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().ToTable(“MyTableName”,schemaName:“MySchemaName”);
请注意以下事项:

一个很好的学习参考:

这是一个不错的解决方案。我必须显式地将每个实体映射到一个表,这真是太糟糕了。我有很多。我希望我能指定一个默认的模式名。或者我希望,如果EF决定使用“dbo”,那么它在运行SQL时应该在表名前面显式添加“dbo”。@AlexFord True。希望有一个添加自定义约定的工具。我接受了这个,但我没有使用它。这确实是一个解决方案,但我选择了easy选项,只需使用Damien_the_unsiver的选项更改数据库用户的默认模式
ALTER user admin with default_schema=dbo
。现在,默认情况下,将在dbo下创建未指定架构的新表。谢谢Alex Ford,在研究了1000页并尝试了10种不同的解决方案后,我终于找到了您的评论:D这是唯一适合我的解决方案,也是最好的解决方案。@JBeckton在提出此问题时您还不能。EF4.3代码优先是一个非常早期的代码优先实现。此问题与EF的最新版本无关。您可以尝试为您的管理员帐户运行,并将
dbo
指定为默认架构。(这并没有回答所提出的问题,但可能是一个解决方案)我实际上更喜欢这个解决方案,而不是手动指定表映射。这个问题的标题是“我可以先更改entity framework 4.3代码中的默认模式名称吗?”被接受的答案是我认为最能回答这个问题的答案。这个问题首先与最新版本的EF代码无关。这只是EF 4.3代码中的一个问题。我相信5岁以上的人不再有这个问题了。耶!我很高兴他们终于添加了本机支持。如果您想完全不使用模式,这也适用于SQLCE。只需使用
String.Empty
。对于那些想知道的人,是的,你可以只添加这一行代码,只要你没有显式地在表上设置架构,当你进行“添加迁移”时,它们都会“移动”,然后是“更新数据库”。我对标记的答案有一个评论。。。有没有办法获取默认模式的值?没有模型生成器?是的,虽然我忘了这就是我再次搜索的原因,但这是正确的答案,因为它甚至将迁移表移动到了这个模式。。。
modelBuilder.Entity<Blog>().ToTable("MyTableName", schemaName:"MySchemaName");