Reputation: 53
I'm using the following classes for a one-to-many relationship:
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; }
}
I'm using ASP.NET MVC 4 and upon Create of a new Contact, the SupplierId is passed in the querystring and added to the Contact create form as a hidden field:
@Html.HiddenFor(model => model.SupplierId)
This creates the Contact successfully and populate's the Contact's SupplierId field with the Guid from the query string. However, the problem is that the Contacts table has another field for the virtual Supplier relationship called Supplier_SupplierId and this field is NULL. I'm not sure I understand why Supplier_SupplierId is even being created on the Contacts table, as SupplierId should be being used as the foreign key and this would just be redundant. If I try to access the Contacts collection of a Supplier I successfully added a Contact to, the collection comes back empty because Contact.Supplier_SupplierId is NULL. However, if I copy the value from the SupplierId column into the Supplier_SupplierId column of the Contact record, Supplier.Contacts will bring back the Contact.
This is what my Contacts table ends up looking like:
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])
);
Does anyone know why 2 foreign keys to Suppliers are being created in Contacts? How can I change it so that the only foreign key to Suppliers is SupplierId?
Upvotes: 5
Views: 4342
Reputation: 177133
This mapping is wrong (I'm refering to your comment below your question):
modelBuilder.Entity<Contact>()
.HasRequired(r => r.Supplier)
.WithMany()
.HasForeignKey(f => f.SupplierId)
.WillCascadeOnDelete(false);
You need:
modelBuilder.Entity<Contact>()
.HasRequired(r => r.Supplier)
.WithMany(s => s.Contacts)
.HasForeignKey(f => f.SupplierId)
.WillCascadeOnDelete(false);
Otherwise EF will consider Supplier.Contacts
as a navigation property that belongs to another and second one-to-many relationship between Supplier
and Contact
- and that introduces the second foreign key.
Upvotes: 6