2011-06-08 3 views
9

Je souhaite créer une relation bidirectionnelle One-One entre deux entités à l'aide du code EF First. J'ai des problèmes avec le code suivant. Que penses-tu que je devrais faire? Je souhaite avoir à la fois la propriété Navigation et la clé étrangère dans les deux entités.Création d'une relation BiDirectional One - One dans Entity Framework 4.1 Code First

Cela me donne une erreur. Que puis-je faire dans Fluent Mapping API pour que cela fonctionne?

+0

Quelle est l'erreur que vous obtenez? – Eranga

Répondre

17

Utilisez ceci:

public class User 
{ 
    public string ID { get; set; } 
    public string LastName { get; set; } 
    public string Password { get; set; } 
    public string FirstName { get; set; } 
    public Profile Profile { get; set; } 
} 

public class Profile 
{ 
    [Key, ForeignKey("User")] 
    public int ProfileID { get; set; } 
    public string ProfileName { get; set; } 
    public DateTime CreateDate { get; set; } 
    public DateTime LastUpdateDate { get; set; } 
    public User User { get; set; } 
} 

C'est la seule façon valable de construire une relation univoque dans EF - PK de l'entité dépendante doit être aussi FK à l'entité principale. Il n'y a rien de tel qu'une relation bi-directionnelle bidirectionnelle dans EF car elle ne peut pas fonctionner dans EF.

La façon dont les gens surmontent parfois ce sont deux relations un-à-plusieurs où le principal n'a pas de collection de navigation pour les entités dépendantes + les clés uniques définies manuellement dans la base de données. Qui nécessitent la cartographie manuelle:

public class User 
{ 
    public string ID { get; set; } 
    public string LastName { get; set; } 
    public string Password { get; set; } 
    public string FirstName { get; set; } 
    // one side MUST be nullable otherwise you have bidirectional constraint where each 
    // entity demands other side to be inserted first = not possible 
    public int? ProfileId { get; set; } 
    public Profile Profile { get; set; } 
} 

public class Profile 
{ 
    public int ProfileID { get; set; } 
    public string ProfileName { get; set; } 
    public DateTime CreateDate { get; set; } 
    public DateTime LastUpdateDate { get; set; } 
    public int UserId { get; set; } 
    public User User { get; set; } 
} 

Et mapping vous définirez:

modelBuilder.Entity<User> 
      .HasOptional(u => u.Profile) 
      .WithMany() 
      .HasForeignKey(u => u.ProfileId); 
modelBuilder.Entity<Profile> 
      .HasRequired(u => u.User) 
      .WithMany() 
      .HasForeignKey(u => u.UserId); 

Maintenant, vous devez définir des clés uniques dans la base de données - si vous utilisez le code d'abord utiliser custom database initialize r. Sachez que le bidirectionnel un-à-un est un concept erroné car les deux côtés exigent un FK unique où NULL est toujours inclus dans des valeurs uniques, donc une fois que vous insérez User avant Profile, il ne doit pas y avoir d'autre User sans Profile. Cela conduit probablement à une transaction sérialisable.

+0

Ladislav, Maintenant, il est parfaitement logique ... Je comprends comment les relations sont établies ... même si je suis d'accord, il aurait dû être mieux pris en charge que la création de clé unique manuellement ... – InvisibleDev

+0

pourquoi WithMany si cela est un- à une relation? – angel

+0

@angel: Il s'agit d'une solution de contournement pour surmonter les limitations d'EF - la deuxième partie de la réponse consiste à tromper EF en lui disant qu'il y a deux relations un-à-plusieurs au lieu d'une correspondance directe. Le one-to-one est assuré au niveau de la base de données en mettant des contraintes de clé uniques sur les colonnes de clé étrangère. –

Questions connexes