web-dev-qa-db-fra.com

Un à zéro ou un avec HasForeignKey

J'ai deux modèles:

public class Person
{
    public virtual int Id { get; set; }
    public virtual Employee Employee { get; set; } // optional
}

public class Employee
{
    public virtual int Id { get; set; }
    public virtual int PersonId { get; set; }

    public virtual Person Person {get; set; } // required
}

public class EmployeeConfiguration : EntityTypeConfiguration<Employee>
{
    public EmployeeConfiguration()
    {
        Property(e=>e.PersonId) // I need this property mapped
            .HasColumnName("person_id")
            .HasColumnType("int");
    }
}

Je veux les cartographier en utilisant une cartographie fluide. La table des employés a la colonne 'person_id' qui n'est pas nullable. J'ai essayé de suivre:

HasRequired(e => e.Person)
    .WithOptional(p => p.Employee)
    .Map(m => m.MapKey("person_id"));

Mais cela échoue avec:

System.Data.Entity.ModelConfiguration.ModelValidationException: une ou plusieurs erreurs de validation ont été détectées lors de la génération du modèle:

person_id: Name: Chaque nom de propriété dans un type doit être unique. Le nom de propriété 'person_id' est déjà défini.

J'ai besoin de la propriété PersonId seule, donc ce que je veux essentiellement, c'est:

HasRequired(e => e.Person)
    .WithOptional(p => p.Employee)
    .HasForeignKey(e => e.PersonId); // there is no such method

Mais il n'y a pas une telle méthode ici comme HasForeignKey

31
joozek

OK, j'ai compris cela - vous devriez utiliser WithMany (oui, pas évident) afin de stocker la clé étrangère dans une propriété:

Property(e => e.PersonId).HasColumnName("person_id");
HasRequired(e => e.Person)
    .WithMany()
    .HasForeignKey(p => p.PersonId);

Voir One-to-One Foreign Key Associations article pour plus de détails. BTW cela créera une colonne de clé étrangère d'employé pour la table de la personne, mais il n'y a pas d'autre moyen d'avoir la propriété de navigation et la clé étrangère séparément.


Si vous avez besoin d'une clé étrangère en lecture seule, vous pouvez modifier la propriété PersonId en:

public int PersonId { get { return Person.Id; } }

Et utilisez votre cartographie d'origine

HasRequired(e => e.Person)
    .WithOptional(p => p.Employee)
    .Map(m => m.MapKey("person_id"));
47
Sergey Berezovskiy

Il existe en fait une meilleure façon de procéder:

HasKey(e => e.PersonId);

HasRequired(e => e.Person)
    .WithOptional(p => p.Employee);

Notez que vous n'avez plus besoin du Employee.Id propriété avec cette approche, car elle était superflue en termes de relation 1 à 0 ou 1 en premier lieu.

5
joelmdev