【问题标题】:Entity Framework issues - appends a "1" to my table name?实体框架问题 - 将“1”附加到我的表名?
【发布时间】:2014-02-20 12:12:52
【问题描述】:

我制作了以下模型优先(这就是它的名称吗?)图表。我使用T4 来生成类。

现在,我遇到了一个问题,导致实体框架以某种方式将“1”附加到DatabaseSupporter 实体的表名。数据库就是从这个模型生成的,没有任何修改。

我正在尝试执行以下行:

_entities.DatabaseSupporters.SingleOrDefault(s => s.Id == myId);

执行该行时收到的错误(以及下面的内部异常)是:

类型异常 'System.Data.Entity.Core.EntityCommandExecutionException' 发生在 mscorlib.dll 但未在用户代码中处理。

无效的对象名称“dbo.DatabaseSupporter1”。

我尝试使用以下 Fluent API 代码解决问题(注意函数中将表显式命名为“DatabaseSupporter”的第二行),但没有成功。

protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{

    modelBuilder
        .Entity<DatabaseSupporter>()
        .HasOptional(f => f.DatabaseChatSession)
        .WithOptionalPrincipal(s => s.DatabaseSupporter);

    modelBuilder
        .Entity<DatabaseSupporter>()
        .Map(m =>
        {
            m.Property(s => s.Id)
                .HasColumnName("Id");
            m.ToTable("DatabaseSupporter");
        });

    modelBuilder
        .Entity<DatabaseSupporter>()
        .HasMany(s => s.DatabaseGroups)
        .WithMany(g => g.DatabaseSupporters)
        .Map(m =>
        {
            m.ToTable("DatabaseSupporterDatabaseGroup");
            m.MapLeftKey("DatabaseGroups_Id");
            m.MapRightKey("DatabaseSupporters_Id");
        });

    modelBuilder
        .Entity<DatabaseGroup>()
        .HasRequired(g => g.DatabaseChatProgram)
        .WithMany(c => c.DatabaseGroups);

    modelBuilder
        .Entity<DatabaseGroup>()
        .HasRequired(g => g.DatabaseOwner)
        .WithMany(o => o.DatabaseGroups);

    modelBuilder
        .Entity<DatabaseOwner>()
        .HasMany(o => o.DatabaseChatSessions)
        .WithRequired(o => o.DatabaseOwner);

    base.OnModelCreating(modelBuilder);
}

应该提到的是,每个实体的Id 属性实际上是一个Guid

我正在使用实体框架 6.0.2。

有什么想法吗?

编辑 1 这是生成的 DatabaseSupporter.cs 文件,其中包含我在 cmets 中请求的 DatabaseSupporter 实体。

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Manual changes to this file may cause unexpected behavior in your application.
//     Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace Coengage.Data.Entities
{
    using System;
    using System.Collections.Generic;

    public partial class DatabaseSupporter
    {
        public DatabaseSupporter()
        {
            this.DatabaseGroups = new HashSet<DatabaseGroup>();
        }

        public bool IsActive { get; set; }
        public string Username { get; set; }
        public System.Guid Id { get; set; }

        public virtual DatabaseChatSession DatabaseChatSession { get; set; }
        public virtual ICollection<DatabaseGroup> DatabaseGroups { get; set; }
    }
}

编辑 2 在我添加DatabaseSupporterDatabaseGroup 之间的多对多链接后,错误开始出现。在该链接之前,也不需要 Fluent 代码。

【问题讨论】:

  • 我之前没有使用T4 生成任何类,因为我创建了所有类,然后让实体框架创建数据库(代码优先)。你能发布你的POCO 类或T4 一代背后的方法吗?尝试使用 fluent API 更改表名将无法正常工作,因为它的类是错误的。
  • 我使用的是默认的 T4 模板。实体框架为我生成类,但它使用的是 T4。关键是 T4 模板没有被修改。
  • 它是否创建了一个您可以查看/发布的 POCO 类?
  • 那个文件看起来很正常。我不太清楚为什么这是一个部分课程......我的想法已经不多了。 Invalid object name 'dbo.DatabaseSupporter1' 表明它正在寻找一个真正的数据库,或者至少 web.config 或 app.config 正在寻找它。我会执行 Ctrl+F 并查看“dbo.DatabaseSupporter1”是否在代码中。如果没有,假设您使用 SQL Server,请检查 SQL Express 没有现有数据库。除此之外,我不认为我可以帮助交配。祝你好运。
  • 添加多对多关系后是否重新生成数据库?为了处理多对多关系,我相信如果没有在模型中显式创建一个关系表,Entity 会创建一个关系表。那可能是在其名称后附加 1 引用的表。

标签: c# entity-framework ef-model-first


【解决方案1】:

此映射不正确:

modelBuilder
    .Entity<DatabaseSupporter>()
    .Map(m =>
    {
        m.Property(s => s.Id)
            .HasColumnName("Id");
        m.ToTable("DatabaseSupporter");
    });

它是Entity Splitting 映射的 50% - 将单个实体的属性存储在两个(甚至更多)单独的表中的映射,这些表通过数据库中的一对一关系链接。由于映射不完整,您甚至无法获得正确的实体拆分映射。特别是 EF 似乎假定包含其他属性(未在映射片段中明确配置)的第二个表应该具有名称 DatabaseSupporter1。我可以用 EF 6 重现它(顺便说一下,它添加了一个 Property 方法来配置映射片段中的单个属性。在早期版本中,该方法不存在(只有 Properties 方法)。)也是一个未在数据库中正确创建一对一约束。在我看来,EF 应该在这里抛出一个关于不正确映射的异常,而不是无声无息地将模型映射到无意义的情况。

无论如何,您可能不想将实体属性拆分到多个表中,而是将其映射到单个表中。然后,您必须将上面的代码块替换为:

modelBuilder.Entity<DatabaseSupporter>()
    .Property(s => s.Id)
    .HasColumnName("Id");

modelBuilder.Entity<DatabaseSupporter>()
    .ToTable("DatabaseSupporter");

第一个映射似乎是多余的,因为属性Id 将默认映射到具有相同名称的列。第二个映射也可能是多余的(取决于表名复数是否打开)。您可以在没有此映射的情况下尝试它。在任何情况下,您都不应该再收到抱怨缺少dbo.DatabaseSupporter1 的异常。

【讨论】:

    【解决方案2】:

    我已完全按照您列出的方式复制了您的模型,我目前无法在 EDMX 表面从模型生成数据库时发出的 DDL 中重现您的问题。

    您能否提供详细信息,说明您将如何在 DatabaseGroup 和 DatabaseSupporter 之间添加多对多关系?你说你试图在 edmx 表面上添加关系,而不是通过代码,它会在你的表名上乱码?

    我将这个东西从 DatabaseGroup 多对多添加到 DatabaseSupporter 我将这个东西从 DatabaseSupporter 多对多添加到 DatabaseGroup

    您能否提供以下信息:

    在添加多对多关系之前回滚到您的代码库。确保您的 EF Fluent API 代码当前不在您的项目中。

    • 从此表面生成 DDL 并确认它不是 以名称 DatabaseSupporters1 生成(发布表名 它在这个阶段选择。数据库支持者或数据库支持者)

    现在,右键单击 DatabaseGroup|新增|协会

    • 为左侧选择 DatabaseGroup,为左侧选择 DatabaseSupporter 对。确认设计者的协会名称 选择的是 DatabaseGroupDatabaseSupporter [不创建]
    • 为左侧选择 DatabaseSupporter,为左侧选择 DatabaseGroup 对。确认设计者的协会名称 选择的是 DatabaseSupporterDatabaseGroup [创建]

    从 edmx 表面,右键单击刚刚创建的多对多关联,然后单击“在模型浏览器中显示”

    • 编辑您的帖子以包含显示的设置。

    另外,右键单击表面并单击“从模型生成数据库”。

    • 编辑您的帖子以包含生成的 DDL。桌子 应命名为 [DatabaseSupporters]

    (我的第一个倾向是它与您的导航属性有关,但并不完全确定。实际上,在我正在从事的玩具项目中,Entity Framework 对我做了同样的事情,但我记得它是纠正起来微不足道,我不记得根本原因是什么;我似乎记得它与导航属性有关)

    [编辑] 等等.....

    如果我删除不能解决我的问题的多对多。然而, 恢复到我添加多对多修复它之前。确切的代码 已经显示了引发异常的情况。如果我删除我的流利 完全映射,抛出的异常不同(它抛出 关于团体、支持者和校长的事情)。我没有 尝试在一个空项目中重新创建模型 - 这需要很多时间 时间。我已经尝试在记事本中搜索 EDMX 以获取参考 - 没有找到。

    (请注意我添加的重点) 那么DatabaseSupporter1 错误是在你尝试了 fluent api 补丁之后出现的?去掉补丁,添加多对多,然后给我们真正的错误。

    ...另外,我花了 5 分钟来构建这个图表。我不认为这是“很多时间”。

    【讨论】:

    • 是的,我认为流畅的解决方法是不必要的,最好专注于让 EF 正常打球。从头开始重新创建并分析 SQL 是一种更好的方法。
    【解决方案3】:

    我面前没有我的开发环境,但我的直接想法是:

    第一

    您的流利看起来不错 - 但您 ID 列中的复数 s 是否正确?表名上没有复数?这将与惯例相反。

    第二次

    EF 将自动附加一个数字来解决名称冲突。在此处查看类似问题:Why does EntityFramework append a 1 by default in edmx after the database entities?

    您是否有任何问题 - 从您的解决方案中删除但仍在构建路径中的代码文件?您是否尝试过使用 Windows 资源管理器而不是 Visual Studio 搜索源文件夹?

    【讨论】:

    • 我没有发现任何地方表明存在重复。没有 EDMX 文件或其他任何文件的副本,在 Windows 资源管理器中搜索文件不会返回任何内容。
    • @MathiasLykkegaardLorenzen 您没有未标记为部分的 DatabaseSupporter 部分类?
    • 不。如果我将类更改为非部分类,它仍然可以编译。
    【解决方案4】:
       modelBuilder
        .Entity<DatabaseSupporter>()
        .HasMany(s => s.DatabaseGroups)
        .WithMany(g => g.DatabaseSupporters)
        .Map(m =>
        {
            m.ToTable("DatabaseSupporterDatabaseGroup");
            m.MapLeftKey("DatabaseGroups_Id");
            m.MapRightKey("DatabaseSupporters_Id");
        });
    

    在多对多上左右颠倒。 试试这个:

       modelBuilder
        .Entity<DatabaseSupporter>()
        .HasMany(s => s.DatabaseGroups)
        .WithMany(g => g.DatabaseSupporters)
        .Map(m =>
        {
            m.ToTable("DatabaseSupporterDatabaseGroup");
            m.MapLeftKey("DatabaseSupporters_Id");
            m.MapRightKey("DatabaseGroups_Id");
        });
    

    【讨论】:

      【解决方案5】:

      我认为DatabaseSupporter 类创建了两次

      一个名字是:DatabaseSupporter

      另一个是:DatabaseSupporter1

      修改后的更改存储在DatabaseSupporter1 并映射到此处。

      您需要复制 DatabaseSupporter1 类代码并将代码粘贴到 DatabaseSupporter 类。然后删除这个DatabaseSupporter1 类。

      【讨论】:

        【解决方案6】:

        我在重命名图中的表格时遇到了这个问题,特别是只更改了大小写。

        如果您通过单击图表中的标题重命名表,我认为它会在尝试更改实体集名称之前检查它,发现它存在(即使它是相同的实体集),并附加一个 1。

        但是,如果您右键单击并打开Properties 窗格并先重命名Entity Set Name,然后再更改Name,则不会添加数字。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-06-20
          • 1970-01-01
          • 2012-03-13
          • 1970-01-01
          • 1970-01-01
          • 2013-08-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多