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

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])
);

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

最佳答案

此映射是错误的(我指的是您的问题下方的评论):

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之间的另一个第二对多关系-并引入了第二个外键。

10-04 22:24
查看更多