【问题标题】:Can't have the same table names in different entity framework models?在不同的实体框架模型中不能有相同的表名?
【发布时间】:2010-11-01 13:13:41
【问题描述】:

我的应用程序使用两个不同的 SQL 2008 数据库。数据库有几个同名的表,即。 Users。我想对这两个数据库都使用 EF4。但是,当我运行我的应用程序并遇到第二个数据库的 objectcontext 创建时,我收到以下错误:

存在多个名为“用户”的类型 在不同的 EdmItemCollection 中 命名空间。基于约定的映射 需要唯一的名称而不考虑 到 EdmItemCollection 中的命名空间到 EdmItemCollection 中的命名空间

这是否意味着我不能在同一个应用程序中使用具有(部分)相同表名的两个数据库?它们位于不同的命名空间、不同的 edmx 模型、不同的项目等中。

附:其中一个模型是设计者生成的,使用 POCO 类,另一个是从数据库中推断出来的,并且与 EF 紧密耦合。

【问题讨论】:

  • 在 Designer 中更改其中一个的实体名称会解决这个问题吗?不过,这似乎有点不方便。
  • 我希望有一个不同的解决方案。这是一个数据库转换应用程序(从旧数据库到新数据库),因此有很多相同的表名。除了以错误的类型名称结束之外,在设计器中重命名它们意味着在新应用程序中进行一些严重的重构。
  • 我有相同的问题,但实体名称不同...

标签: c# .net sql-server entity-framework


【解决方案1】:

要使用“基于默认约定的映射”,可以使用以下两种方法:

1) 冲突是由使用通配符的连接字符串引起的:

    metadata=res://*/Repositories.EntityFramework.Model.csdl|res://*/Repositories.EntityFramework.Model.ssdl|res://*/Repositories.EntityFramework.Model.msl;

由于 * 不适用于您的项目,您可以定义多个连接字符串来硬编码包含 edmx 的程序集。

2) 创建一个助手

    public static EntityConnection GetEfConnectionString(this string sqlConnectionString)
    {
        var cs = string.Format(@"metadata=res://{0}/Repositories.EntityFramework.Model.csdl|res://{0}/Repositories.EntityFramework.Model.ssdl|res://{0}/Repositories.EntityFramework.Model.msl;provider=System.Data.SqlClient;provider connection string=""" + sqlConnectionString + @"""",
            Assembly.GetCallingAssembly().FullName
        );

        return new EntityConnection(cs);
    }

2017 年更新:

    public static string GetEfConnectionString(this string sqlConnectionString, Type type)
    {
        string cs =
            string.Format(
                @"metadata=res://{0}/Models.Model.csdl|res://{0}/Models.Model.ssdl|res://{0}/Models.Model.msl;provider=System.Data.SqlClient;provider connection string=""" +
                sqlConnectionString + @"""",
                type.Assembly.FullName
                );
        return cs;
    }


    // usage: don't "new" EntityConnection.  See 2012 comment.
    string connString = ConfigurationManager.ConnectionStrings["sqlConnection"].ConnectionString.GetEfConnectionString();
    using(var entities = new XyzEntities(connString))

【讨论】:

  • 这对我帮助很大。我修改了我的 T4 模板来实现类似的东西,这样所有模型都可以使用配置中的一个连接字符串,但仍然只能读取它们的元数据。谢谢。
  • 我刚刚获得投票并想更新这个...不要新建 EntityConnection 否则您需要管理打开/关闭对象。您的助手应该将连接字符串作为字符串返回,并在 objectcontext ef4.0 或 dbcontext ef4.1 上使用重载构造函数。
  • +1 用于更简单的解决方案,它也可以在没有 Code First 的情况下工作。
  • 我已经创建了多个连接字符串,但是没有消除通配符...如何消除通配符?
  • 我知道这是一个老问题,但有人能告诉我如何使用上述扩展方法吗?另外,我使用的是 EF6,而不是 4。例如,我的 dbContext 生成的代码使用“name=string”调用 DbContext .ctor,所以我必须使用带有连接字符串的 .ctor 重载手动修改它?
【解决方案2】:

错误的意思是,他说的是:您不能在您的场景中使用基于默认约定的映射。请改用自定义数据库映射。 Scott Guthrie 有一篇关于 this 的详细博客文章。

【讨论】:

    【解决方案3】:

    我有同样的问题,但我的解决方案是从项目中删除 MODEL\edmx 的 DLL,因为它是从不同的项目中复制的,然后重新构建它。 解决一切!

    【讨论】:

      【解决方案4】:

      这个错误的另一个原因是发生在我身上的事情:我的项目是从其他地方复制的,我重命名了项目,所以编译后我的 bin 文件夹中有 2 个 DLL。上一个项目的一个和一个全新的,根据新项目命名。一旦我删除了以前/旧的 DLL,命名空间的歧义就消失了,错误也消失了。

      【讨论】:

        【解决方案5】:

        对于 DB 优先方法,幸运的是有几个非常简单的解决方法:

        1. 确保两个上下文不共享相同的表 名称 - 不是最实用的方法。
        2. 通过以下方式重构解决方案 在它们自己的程序集中隔离数据库上下文。

        更多详情请参考link

        解释得很清楚。

        【讨论】:

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