【问题标题】:EF using code first with one-to-many relationship creating duplicate foreign keysEF首先使用具有一对多关系的代码创建重复的外键
【发布时间】:2012-07-19 08:14:53
【问题描述】:

我将以下类用于一对多关系:

public class Supplier
{
    public Supplier()
    {
        SupplierId = Guid.NewGuid();
    }

    public Guid SupplierId { get; set; }
    [Required]
    public string Name { get; set; }

    [Required]
    public virtual Address Address { get; set; }

    public virtual ICollection<Contact> Contacts { get; set; }
}

public class Contact
{
    public Contact()
    {
        ContactId = Guid.NewGuid();
    }

    public Guid ContactId { get; set; }

    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }

    [Required]
    public Guid SupplierId { get; set; }
    [ForeignKey("SupplierId")]
    public virtual Supplier Supplier { get; set; }
}

我使用的是 ASP.NET MVC 4,在创建新联系人时,SupplierId 会在查询字符串中传递并作为隐藏字段添加到联系人创建表单中:

@Html.HiddenFor(model => model.SupplierId)

这将成功创建联系人并使用查询字符串中的 Guid 填充联系人的 SupplierId 字段。但是,问题在于 Contacts 表有另一个名为 Supplier_SupplierId 的虚拟供应商关系字段,该字段为 NULL。我不确定我是否理解为什么会在 Contacts 表上创建 Supplier_SupplierId,因为 SupplierId 应该用作外键,而这只是多余的。如果我尝试访问已成功添加联系人的供应商的联系人集合,则该集合返回为空,因为 Contact.Supplier_SupplierId 为 NULL。但是,如果我将 SupplierId 列中的值复制到 Contact 记录的 Supplier_SupplierId 列中,Supplier.Contacts 将带回 Contact。

这是我的联系人表最终的样子:

CREATE TABLE [dbo].[Contacts] (
    [ContactId]           UNIQUEIDENTIFIER NOT NULL,
    [FirstName]           NVARCHAR (MAX)   NOT NULL,
    [LastName]            NVARCHAR (MAX)   NOT NULL,
    [Supplier_SupplierId] UNIQUEIDENTIFIER NULL,
    CONSTRAINT [PK_dbo.Contacts] PRIMARY KEY CLUSTERED ([ContactId] ASC),
    CONSTRAINT [FK_dbo.Contacts_dbo.Suppliers_SupplierId] FOREIGN KEY ([SupplierId]) REFERENCES [dbo].[Suppliers] ([SupplierId]),
    CONSTRAINT [FK_dbo.Contacts_dbo.Suppliers_Supplier_SupplierId] FOREIGN KEY ([Supplier_SupplierId]) REFERENCES [dbo].[Suppliers] ([SupplierId])
);

有谁知道为什么要在联系人中创建供应商的 2 个外键?如何更改它以使 Suppliers 的唯一外键是 SupplierId?

【问题讨论】:

  • 你有 Fluent API 的映射吗?您是否删除了一些约定?您显示的类是否完整,或者SupplierContact 之间是否有更多导航属性?
  • 我正在重写 OnModelCreating 函数以更正多个级联路径错误:modelBuilder.Entity() .HasRequired(r => r.Supplier) .WithMany() .HasForeignKey(f => f.SupplierId) .WillCascadeOnDelete(false);我从类中删除了一些不适用于此问题的简单属性,但类之间没有引用。从供应商到联系人只有一对多。

标签: asp.net asp.net-mvc entity-framework ef-code-first


【解决方案1】:

这个映射是错误的(我指的是你在问题下方的评论):

modelBuilder.Entity<Contact>()
    .HasRequired(r => r.Supplier)
    .WithMany()
    .HasForeignKey(f => f.SupplierId)
    .WillCascadeOnDelete(false);

你需要:

modelBuilder.Entity<Contact>()
    .HasRequired(r => r.Supplier)
    .WithMany(s => s.Contacts)
    .HasForeignKey(f => f.SupplierId)
    .WillCascadeOnDelete(false);

否则 EF 会将 Supplier.Contacts 视为属于 SupplierContact 之间的另一个和第二个一对多关系的导航属性 - 并引入第二个外键。

【讨论】:

  • 谢谢!那是罪魁祸首。
  • 您指出了我犯的完全相同的错误。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-16
  • 1970-01-01
  • 1970-01-01
  • 2018-05-31
相关资源
最近更新 更多