2013-06-27 17 views
7

Ich versuche, ein Entity Framework-Modell mit einer optionalen einzurichten: optional Beziehung:Entity Framework optional: optional Beziehung

In meiner Situation, manchmal ein AdditionalData Datensatz vorhanden ist, dass Punkte auf einen BaseTable Rekord, aber manchmal BaseTable oder AdditionalData-Datensätze existieren ohne jegliche Verknüpfung. Der Fremdschlüssel für die BaseTable (falls vorhanden) befindet sich in der AdditionalData-Tabelle.

Ich möchte in der Lage sein, zwischen BaseTable und alle zusätzlichen Daten, die möglicherweise verbunden sind, hin und her navigieren.

BaseTable 0..1 ----- 0..1 AdditionalData1 
       \ 
        --- 0..1 AdditionalData2 


public class BaseTable { 
    public int Id { get; set; } 
    public virtual AdditionalType1 AdditionalType1 { get; set; } 
    public virtual AdditionalType2 AdditionalType2 { get; set; } 
}     

public class AdditionalType1 { 
    public int Id { get; set; } 
    public int? BaseTableId { get; set; } 
    public virtual BaseTable BaseTable { get; set; } 
} 

public class AdditionalType2 { 
    public int Id { get; set; } 
    public int? BaseTableId { get; set; } 
    public virtual BaseTable BaseTable { get; set; } 
} 

Wie mache ich diese Arbeit? Ich habe so weit wie:

modelBuilder.Entity<AdditionalType1>() 
    .HasOptional(zmt => zmt.BaseTable) 
    .WithOptionalDependent(zm => zm.AdditionalType1) 
    .Map(a => a.MapKey("BaseTableId")); 
modelBuilder.Entity<AdditionalType2>() 
    .HasOptional(zmt => zmt.BaseTable) 
    .WithOptionalDependent(zm => zm.AdditionalType2) 
    .Map(a => a.MapKey("BaseTableId")); 

aber es sagt mir dies:

error: (1564,6) : error 0019: Each property name in a type must be unique. Property name 'BaseTableId' was already defined.

Ich weiß nicht genau, was das bedeutet, und nicht sicher, wie sie zu beheben.

EDIT: Wenn ich die Karte/MapKey Klauseln entfernen, wie hier vorgeschlagen (https://stackoverflow.com/a/8016308/237091) ich diesen Fehler stattdessen, wenn eine Abfrage ausgeführt wird, dass es verwendet:

Invalid column name 'BaseTable_Id' as it maps itself to BaseTable_Id automatically instead of my BaseTableId field.

+1

'Manchmal ist eine BaseTable vorhanden' Sie möchten entweder Zeilen in der Basistabelle für Benutzer erstellen oder Sie haben ein sehr schlechtes Verständnis davon, wie Datenbanken funktionieren. Es ist nicht wie Schrödingers Katze, ob deine Datenbank eine Tabelle hat, die zur Entwurfszeit bestimmt werden muss. – MrFox

+0

@Mr Fox: Zur Verdeutlichung bearbeitet - ich redete über Aufzeichnungen, nicht die tatsächliche Existenz der Tabelle. –

Antwort

5

Es sieht aus wie Sie festlegen, sind versucht, eine 1: 0..1 Beziehung von Ihren AdditionalType Objekten (die ich möglicherweise falsch interpretiert haben könnte.

NB Ich denke, Sie müssten eine BaseTableId auf Ihrem BaseTable halten, damit dies funktioniert (oder einen Primärschlüssel definieren):

Wenn BaseTableId der Fremdschlüssel in diesem Fall ist, ich denke, das sein kann, was Sie nach:

modelBuilder.Entity<AdditionalType1>() 
    .HasOptional(zmt => zmt.BaseTable) 
    .WithMany() 
    .HasForeignKey(a => a.BaseTableId); 

Welche ist das, was ich vorher benutzt habe, aber es vollständig zu verstehen (die nicht zugeben kann. WithMany() stolpert mich); es ist eine kleine Problemumgehung, die im Artikel von dieser Antwort aufgeführt wird: Entity Framework 0..1 to 0 relation)

Entschuldigung, wenn ich den Punkt völlig verpasst habe.

+1

ja verwenden Sie diesen Ansatz. Dies ist 1: Viele, aber Sie sind nicht gezwungen, viele Einträge zu setzen ;-) 1: 1-Deklaration würde Basistabelle und zusätzliche erfordern, um den gleichen Primärschlüssel zu haben. Und eines als Primary markiert. So muss eine benutzerdefinierte Überprüfung hinzufügen oder einen eindeutigen Index hinzufügen, um 1: 1 zu garantieren –

+0

Ah, vergaß, einen eindeutigen Index zu erwähnen, Ta = D – Chris

+0

Entschuldigung, gerade hinzugefügt Id prooperty. Ich beabsichtigte, dass es ein PK-ID-Feld auf allen von ihnen, aber nicht ein gemeinsamer Primärschlüssel aus Legacy-Gründen. –