2013-06-27 3 views
7

Je suis en train de mettre en place un modèle Entity Framework avec une option: relation en option:Entity Framework en option: relation en option

Dans ma situation, parfois existe un enregistrement AdditionalData qui pointe vers un record BaseTable, mais parfois BaseTable ou Les enregistrements AdditionalData existent sans aucun lien. La clé étrangère à la BaseTable (si elle existe) est sur la table AdditionalData. Je veux être en mesure de naviguer entre BaseTable et toute autre AdditionalDatas qui pourrait être connectée.

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

Comment puis-je faire ce travail? Je suis aussi loin que:

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

mais il me dit ceci:

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

Je ne sais pas exactement ce qui se réfère à, et ne sais pas comment résoudre.

EDIT: Si je retire la carte/clauses MapKey comme le suggère ici (https://stackoverflow.com/a/8016308/237091) Je reçois cette erreur au lieu, lorsqu'une requête est exécutée qui l'utilise:

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

+1

'Parfois, une BaseTable existe' Soit vous voulez créer des lignes dans la table de base pour les utilisateurs, soit vous avez une très mauvaise compréhension du fonctionnement des bases de données. Ce n'est pas comme le chat de Schrodinger, si votre base de données a une table à déterminer au moment du design. – MrFox

+0

@Mr Fox: Edité pour clarification - Je parlais d'enregistrements, pas de l'existence réelle de la table. –

Répondre

5

On dirait que vous essayez de définir un 1:. 0..1 relation de vos objets AdditionalType (que je peux avoir mal interprété complètement

NB Je pense que vous auriez à tenir une BaseTableId sur votre BaseTable pour que cela fonctionne (ou définir une clé primaire):

Si BaseTableId est la clé étrangère dans ce cas, je pense que cela peut être ce que vous êtes après:

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

Ce qui est ce que je l'ai utilisé précédemment, mais ne peut pas admettre pour comprendre pleinement (la. WithMany() me fait voyager); c'est une solution de contournement énumérée dans l'article de cette réponse: Entity Framework 0..1 to 0 relation)

Excuses si j'ai manqué le point entièrement.

+1

Oui, utilisez cette approche. c'est 1: Beaucoup mais vous n'êtes pas obligé de mettre beaucoup d'entrées ;-) La déclaration 1: 1 nécessiterait que la table de base et Additional aient la même clé primaire. Et un à marquer comme primaire. Il faudra donc ajouter un contrôle personnalisé ou ajouter un index unique pour garantir 1: 1 –

+0

Ah, j'ai oublié de mentionner un index unique, Ta = D – Chris

+0

Désolé, vient d'ajouter Id prooperty. Je voulais qu'il y ait un champ PK Id sur chacun d'entre eux, mais pas une clé primaire partagée pour des raisons héritées. –