繁体   English   中英

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

[英]Change Entity framework database schema at runtime

在大多数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中而正在读取已存在的实体。

有什么想法吗?

我有同样的问题,这真的很烦人,因为这是微软真的错过了船的情况之一。 使用EF的一半原因是支持其他数据库,但除非您首先使用代码并不能真正解决问题。

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

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

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

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

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

下面的老答案。

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

同样,如果在运行时更新连接字符串,则必须使用特定工具 ,这些工具可以理解EF连接字符串格式,并且与通常的连接字符串构建器分开。 请参阅链接中的示例。 另请参阅有关分配EF连接字符串的此帮助

对不起,它不是一个强有力的答案,但我在搜索到类似问题时在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()))
    {
    ...
    }

}

看起来它正是你想要的。

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

编辑

你在同一个数据库中有prod和test模式吗?

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

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

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

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

这是一个类似的问题,有一个更好的答案: 在运行时更改模式名称 - 实体框架

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

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

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

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

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


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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM