在运行时更改实体框架数据库模式

时间:2009-11-26 21:46:11

标签: c# asp.net entity-framework

在大多数asp.net应用程序中,您可以通过在运行时修改连接字符串来更改数据库存储。即只需更改connectionstring中“database”字段的值,我就可以从使用测试数据库更改为生产数据库

我正在尝试使用实体框架更改架构(但不一定是数据库本身),但没有运气。

我看到的问题是edmx xml文件中的SSDL内容正在为每个实体集存储架构

见下文

<EntitySet 
    Name="task" 
    EntityType="hardModel.Store.task" 
    store:Type="Tables" 
    Schema="test"  />

现在我已经将schema属性值从test更改为“prod”,它可以工作..

但这似乎不是一个好的解决方案。

  1. 我需要更新外部实体集以及存储过程(我有+50个表)
  2. 我只能在编译时这样做吗?
  3. 如果我稍后尝试更新实体模型 - 由于EF无法识别该表已存在于edm中,正在读取已存在的实体。
  4. 有什么想法吗?

8 个答案:

答案 0 :(得分:6)

我有同样的问题而且它真的很烦人,因为它是微软真正错过这条船的案例之一。使用EF的原因有一半是对其他数据库的支持,但除非您首先使用的代码没有真正解决问题。

在MS SQL中,更改模式毫无意义,因为模式是表的标识的一部分。对于其他类型的数据库,模式非常不是数据库标识的一部分,只能确定数据库的位置。连接到Oracle并更改数据库和更改架构基本上是同义词。

答案 1 :(得分:2)

更新在阅读您的评论后,很明显您希望更改每个数据库的引用架构,数据库。我已经编辑了这个问题以澄清这一点并恢复您提供的样本EDMX,它隐藏在原始格式中。

我将在下面重复我的评论:

  

如果架构在同一个数据库中,则无法在运行时切换这些(除了仅限EF 4代码)。这是因为两个不同模式中的两个具有相同名称和结构的表被视为完全不同的表。

我也同意上面的JMarsch:我会重新考虑将测试和生产数据(或实际上,'任何和生产数据')放在同一个数据库中的设计。似乎是对灾难的邀请。

下面的旧答案。

您确定要更改正确的连接字符串吗? EF使用的连接字符串嵌入内部连接字符串,该字符串指定CSDL / SSDL / etc的位置。拥有一个“普通”连接字符串是常见的,供应用程序的其他部分使用(例如,ASP.NET成员资格)。在这种情况下,更改数据库时,必须更新连接字符串的

同样,如果在运行时更新连接字符串,则必须使用specific tools for this,它了解EF连接字符串格式,并且与通常的连接字符串构建器分开。请参阅链接中的示例。另请参阅this help on assigning EF connection strings

答案 2 :(得分:2)

对不起,这不是一个强有力的答案,但我在搜索codeplex(以及这个问题)时发现了这个项目,同时搜索类似的问题:

http://efmodeladapter.codeplex.com/

功能包括:

  • 模型架构的运行时调整, 包括:
  • 调整数据级表 前缀或后缀
  • 调整 数据库对象的所有者

文档中的一些代码:

public partial class MyObjectContext : BrandonHaynes.ModelAdapter.EntityFramework.AdaptingObjectContext
{
        public MyObjectContext() 
        : base(myConnectionString, 
        new ConnectionAdapter(
            new TablePrefixModelAdapter("Prefix", 
                new TableSuffixModelAdapter("Suffix")), 
        System.Reflection.Assembly.GetCallingAssembly()))
    {
    ...
    }

}

看起来就像你正在寻找的那样。

答案 3 :(得分:1)

EF的连接字符串位于配置文件中。无需更改SSDL文件。

修改

您是否在同一个数据库中拥有prod和test架构?

如果是,您可以使用单独的数据库进行prod和test来修复它。在两个数据库中使用相同的模式名称。

如果否,您可以通过在两个数据库中使用相同的模式名称来修复它。

如果您绝对拥有不同的模式名称,请创建两个EF模型,一个用于测试,一个用于prod,然后根据配置文件中的值选择要在代码中使用的模型。

答案 4 :(得分:1)

解决问题的最简单方法是从模型的SSDL部分手动删除所有条目,如'Schema =“SchemaName”'。
在这种情况下,一切都正常。

答案 5 :(得分:1)

当我创建一个新的“ADO.NET实体数据模型”时,有两个属性“实体容器名称”和“命名空间”可用于在设计视图中进行编辑。使用namespace.EntityContainerName,您可以创建一个新实例指定连接字符串。

MyEntities e = new MyEntities("connstr");
e.MyTable.Count();

我不确定这对你有帮助,祝你好运!

此外,这是多层的一个很好的案例(不一定是项目,但可能是)。


 * DataAccess - 此处的实体
 *服务 - 包含对DataAccess的访问权限  *消费者 - 致电服务

在这种情况下,消费者调用服务,传入任何决定使用哪个连接字符串的因素。然后,该服务实例化一个传入适当连接字符串的数据访问实例,并执行消费者的查询。

答案 6 :(得分:1)

这是一个类似的问题,答案更好: Changing schema name on runtime - Entity Framework

对我有用的解决方案是Jan Matousek撰写的解决方案。

答案 7 :(得分:0)

通过迁移到sql server并远离mysql解决了我的问题。

Mysql和Mssql以不同的方式解释“模式”。 mysql中的模式与数据库相同/同义。当我创建模型时,模式名称...与数据库名称相同,在生成的模型xml中进行了硬编码。在Mssql中,模式默认为“dbo”,它被硬编码,但这不是问题,因为在mssql模式和数据库中是不同的。