2012-07-20 9 views
5

Używam następujące klasy dla relacji jeden-do-wielu:EF pierwszym użyciu kodu z jednego do wielu relacji tworzenie duplikatów kluczy obcych

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; } 
} 

Używam ASP.NET MVC 4 i po Tworzenie nowego styku, SupplierId jest przekazywana w ciągu kwerendy i dodawane do kontaktu utworzyć formularz jak ukrytym polem:

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

stwarza to nas skutecznie i wypełnić to pole kontaktu SupplierId z GUID od ciąg zapytania. Problem polega jednak na tym, że tabela Kontakty zawiera inne pole dla wirtualnej relacji dostawcy o nazwie Supplier_SupplierId, a pole to ma wartość NULL. Nie jestem pewien, rozumiem, dlaczego Supplier_SupplierId jest nawet tworzone na tabeli kontaktów, a SupplierId powinny być używane jako klucz obcy i byłoby to po prostu nadmiarowe. Jeśli próbuję uzyskać dostęp do kolekcji kontaktów dostawcy pomyślnie dodałem kontakt do, kolekcja wraca pusta, ponieważ Contact.Supplier_SupplierId ma wartość NULL. Jeśli jednak skopiuję wartość z kolumny SupplierId do kolumny Supplier_SupplierId rekordu Contact, dostawca.Contacts spowoduje przywrócenie kontaktu.

To właśnie kończy się moja Kontakt stół patrząc jak:

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

Czy ktoś wie dlaczego 2 klucze do dostawców zagranicznych są tworzone w aplikacji Kontakty? Jak mogę to zmienić, aby jedynym kluczem obcym dla Dostawców był SupplierId?

+0

Czy masz jakieś mapowanie w Fluent API? Czy usunąłeś niektóre konwencje? Czy pokazywane klasy są kompletne, czy też istnieje więcej właściwości nawigacji między 'Dostawcą' i' Kontaktem'? – Slauma

+1

ja nadrzędne funkcje OnModelCreating w celu wyeliminowania kaskady z wielu ścieżek błąd: modelBuilder.Entity () .HasRequired (R => r.Supplier) .WithMany() .HasForeignKey (f => F. SupplierId) . WillCascadeOnDelete (false); Usunąłem z klas kilka prostych właściwości, które nie dotyczą tego problemu, ale nie ma żadnych odniesień między klasami. Istnieje tylko jeden do wielu od dostawcy do kontaktów. –

Odpowiedz

6

To odwzorowanie jest źle (ja odnosząc się do komentarza poniżej swoje pytanie):

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

potrzebował:

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

Inaczej EF rozważy Supplier.Contacts jako własność należącą do nawigacji inna i druga relacja jeden-do-wielu między Supplier i Contact - i która wprowadza drugi klucz obcy.

+0

Dziękujemy! To był winowajca. –

+0

Wskazałeś dokładnie ten sam błąd, który popełniłem. Dzięki! –

Powiązane problemy