【问题标题】:Entity Framework is appending "1" to table name and query is failing实体框架将“1”附加到表名并且查询失败
【发布时间】:2026-02-22 10:30:01
【问题描述】:

我们有一个使用 Web Api 和实体框架的电子商务网站。我最近为一个名为“BundleProduct”的实体创建了一个 ApiController。当我在控制器上调用 GET 方法时,我得到一个 System.Data.SqlClient.SqlException: "Invalid object name 'dbo.BundleProducts1'。"

使用 VS 调试器,这是正在执行的查询(此表中只有两列,共同构成一个主键):

SELECT 
[Extent1].[Fk_BundleID] AS [Fk_BundleID], 
[Extent1].[Fk_ProductID] AS [Fk_ProductID]
FROM [dbo].[BundleProducts1] AS [Extent1]

没有“BundleProducts1”表,应该叫“BundleProducts”。我在代码中进行了搜索,找不到任何使用名称“BundleProducts1”的实例。

BundleProducts 表表示“Bundles”表和“Products”表之间的多对多关系。这个特定的表只有两列,两者都是主键。我确实查看了 DbContext 类,它对 BundleProducts 的唯一引用是:

public DbSet<BundleProduct> BundleProducts { get; set; }

modelBuilder.Entity<Bundle>()
.HasMany(e => e.Products)
.WithMany(e => e.Bundles)
.Map(m => m.ToTable("BundleProducts")
.MapLeftKey("Fk_BundleID")
.MapRightKey("Fk_ProductID"));

为什么 EF 会在表名后附加“1”,我该怎么做才能更改?

【问题讨论】:

  • 当你有两个外键映射到同一个表中的不同记录时,我见过 EF 这样做,但我还没有看到它把表名弄错了。你能发布整个 DbContext 吗?
  • Entity Framework 使用数字来解决名称冲突,因此您很有可能遇到名称冲突。我会: 1. 寻找有冲突的课程。 2. 确保一切都是最新的。
  • @victor - 我无法发布整个 DBContext,数据库中有数百个表。
  • @MarkBeleski - 我在项目中进行了搜索,没有冲突的类。

标签: entity-framework asp.net-web-api2


【解决方案1】:

当您使用多对多映射 (HasMany - WithMany) 时,EF 将使用名为 BundleProducts隐藏 关联类。

问题是您还添加了一个 visibleBundleProducts。 EF 尝试执行您指示它执行的操作:将两个类映射到一个表,然后遇到名称冲突。可见类受害并被重命名。

您要么必须从模型中删除可见类,要么将多对多映射转换为两个一对多映射,中间有BundleProductsBundle 1 - n BundleProduct n - Product

【讨论】:

  • 我需要在我的 ApiController 中使用 BundleProducts 类,所以选项 1 对我来说似乎不可行。我将如何实施选项 2?
  • Here 就是一个例子。 Enrollment 是你的BundleProduct
  • 我正在尝试使用该示例对我的代码进行必要的更改。我们使用“现有数据库中的代码优先”,并认为可能缺少某些内容,因为我为数据库中的所有表创建了模型,而 BundleProducts 模型不存在。我创建了一个新项目并选择了 Bundles、Products 和 BundleProducts 表,它只为 Bundles 和 Products 创建了类。它确实像我之前提到的那样引用了 DbContext 中的 BundleProducts,但是如果我再次添加 BundleProducts,它会为我创建类但不能解决问题。
  • 它只是创建了多对多映射(没有可见的联结类),因为BundleProduct 只包含两个外键,没有额外的数据。通常的做法是使用“先从现有数据库中编写代码”作为起点,然后根据需要修改类模型(例如:给它更有意义的导航属性名称)。
  • 如果我请求一个 Bundle,它包含一个 Products 属性,它是 Product 对象的集合。但是,我们的 Web Api 没有公开这些模型,我们使用 DTO,它不包括作为其他类实例的属性(表示关系)。我想我可以修改 DTO 以包含它,但我不想在保存 Bundle 时修改产品。我的目标是检索、保存和删除 BundleProduct 表中的行,但我不知道该怎么做。这是对使用 ADO.NET 访问的存储过程的现有应用程序的重写,而我们没有遇到此问题。