Question

Comment déclarer une relation un à un code utilisant Entity Framework 4 Première (POCO)?

J'ai trouvé cette question (de un relations individuelles dans Entity Framework 4) , mais l'article que les références de réponse n'a pas été utile (il y a une ligne de code qui est une relation 1-1, mais aucune mention de la façon de le définir).

Était-ce utile?

La solution

Vous cherchez juste quelque chose comme ça?

public class User
{
    public int Id { get; set; }
    public string Username { get; set; }
    public Profile Profile { get; set; }
    public int ProfileId { get; set; }
}

public class Profile
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string PostalCode { get; set; }
    // etc...
}

public class UserMapping : EntityConfiguration<User>
{
    public UserMapping()
    {
        this.HasKey(u => u.Id);
        this.Property(u => u.Username).HasMaxLength(32);

        // User has ONE profile.
        this.HasRequired(u => u.Profile);
    }
}

public class ProfileMapping : EntityConfiguration<Profile>
{
    public ProfileMapping()
    {
        this.HasKey(p => p.Id);
        this.Property(p => p.FirstName).HasMaxLength(32);
        this.Property(p => p.LastName).HasMaxLength(32);
        this.Property(p => p.PostalCode).HasMaxLength(6);
    }
}

EDIT : Oui, je n'ai pas eu VS devant moi, mais vous devez ajouter la ligne suivante dans la UserMapping au lieu du courant HasRequired et également ajouter une propriété ProfileId (au lieu de Profile_Id que vous avez ajouté):

this.HasRequired(u => u.Profile).HasConstraint((u, p) => u.ProfileId == p.Id);

Je ne pense actuellement pas qu'il y ait un moyen de contourner cela, mais je suis sûr que ça va changer puisque nous sommes seulement dans CTP4. Ce serait bien si je pouvais dire:

this.HasRequired(u => u.Profile).WithSingle().Map(
    new StoreForeignKeyName("ProfileId"));

De cette façon, je ne voudrais pas inclure une propriété ProfileId. Peut-être il y a un moyen de contourner ce moment et il est encore tôt le matin pour moi de penser:.)

Souvenez-vous également appeler .Include("Profile") si vous souhaitez inclure une « propriété de navigation ».

Autres conseils

Méthodes Trois:

A) Déclarer les deux classes ayant des propriétés de navigation à l'autre. Marquez l'une des tables (la table dépendante) avec l'attribut ForeignKey sur sa clé primaire. EF infère 1 à 1 de ceci:

public class AppUser
{
    public int Id { get; set; }

    public string Username { get; set; }

    public OpenIdInfo OpenIdInfo { get; set; }
}

​public class OpenIdInfo
{
    [ForeignKey("AppUser")]
    public int Id { get; set; }

    public string OpenId { get; set; }

    public AppUser AppUser { get; set; }
}

Entité-Splitting , où vous avez une seule classe, mais il est stocké dans une table primaire et 1 ou plus un à une des tables connexes.

Table-Splitting , où un arbre d'objets aplanit dans une seule table. Par exemple, une classe avec une propriété d'adresse aurait des colonnes pour l'objet d'adresses, comme Address_City, aplati dans une seule table.

* Vous pouvez inclure virtuelle sur une propriété ou EF Collections si vous voulez charge paresseux les . Cela peut entraîner des boucles infinies ou le chargement de la totalité de DB si vous passez un objet avec des propriétés chargées paresseux, par exemple, le convertisseur MVC JSON ou toute autre chose qui marche la hiérarchie des objets. Le Lazy-chargement se fait toujours Synchrone, bloquant le fil, et sans préavis. Pour résumer, la liste des façons dont vous pouvez congeler votre code, l'application ou le serveur avec elle est longue. Évitez d'utiliser les classes virtuelles sur EF. Oui, il y a beaucoup d'exemples de code sur Internet qui l'utilisent. Non, vous devriez toujours pas l'utiliser.

public class User
{
    public int Id { get; set; }
    public string Username { get; set; }

    public virtual Profile Profile { get; set; }
}

public class Profile
{
    public int Id { get; set; }

    public int UserID { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string PostalCode { get; set; }
}

Ajoutez le profil virtuel et l'ID utilisateur et je pense que vous devriez y arriver.

Prenons l'exemple des entités suivantes étudiants et StudentAddress.
Configurer une à zéro ou une relation à l'aide DataAnnotations:

public class Student
{
    public Student() { }

    public int StudentId { get; set; }
    public string StudentName { get; set; }

    public virtual StudentAddress Address { get; set; }

}

public class StudentAddress 
{
    [ForeignKey("Student")]
    public int StudentAddressId { get; set; }

    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public int Zipcode { get; set; }
    public string State { get; set; }
    public string Country { get; set; }

    public virtual Student Student { get; set; }
}

Quand entité StudentAddress ne suit pas les conventions:

Si, par exemple, entité StudentAddress ne suit pas la convention pour PK dire un autre nom de la propriété Id alors vous devez le configurer pour PK ainsi. Considérez l'entité StudentAddress suivante qui a le nom de la propriété StudentID au lieu de StudentAddressId.

public class Student
{
    public Student() { }

    public int StudentId { get; set; }
    public string StudentName { get; set; }

    public virtual StudentAddress Address { get; set; }

}

public class StudentAddress 
{
    [Key, ForeignKey("Student")]
    public int StudentId { get; set; }

    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public int Zipcode { get; set; }
    public string State { get; set; }
    public string Country { get; set; }

    public virtual Student Student { get; set; }
}

Dans l'exemple ci-dessus, nous avons besoin de configurer la propriété de StudentID comme clé ainsi que ForeignKey. Cela rendra la propriété StudentID dans l'entité StudentAddress PK et FK deux.

Configurer un à zéro ou une relation en utilisant l'API Courant: Lorsque des étudiants et StudentAddress suivent les conventions: entités étudiants et StudentAddress suivent la convention de code par défaut pour la première PrimaryKey. , Nous ne devons donc les configurer pour définir leurs PrimaryKeys. Nous ne devons configurer entité StudentAddress où StudentAddressId doit être ForeignKey.

Les jeux exemple suivant un à zéro ou une relation entre l'élève et StudentAddress en utilisant l'API Fluent.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{

    // Configure Student & StudentAddress entity
    modelBuilder.Entity<Student>()
                .HasOptional(s => s.Address) // Mark Address property optional in Student entity
                .WithRequired(ad => ad.Student); // mark Student property as required in StudentAddress entity. Cannot save StudentAddress without Student

}

Dans l'exemple ci-dessus, l'entité Student est configuré en utilisant la méthode HasOptional () qui indique que la propriété de navigation StudentAddress en étudiant entité est une option (non requis lors de l'enregistrement entité de Student). Ensuite, la méthode de l'entité configure WithRequired () et faire la propriété de navigation des étudiants de StudentAddress selon les besoins (requis lors de l'enregistrement entité StudentAddress. Il lancera une exception lorsque l'entité StudentAddress sauve sans propriété de navigation étudiants). Cela fera StudentAddressId comme ForeignKey aussi.

Ainsi, vous pouvez configurer un à zéro ou une relation entre deux entités où entité étudiant peut être enregistrée sans y attacher objet StudentAddress à elle, mais l'entité StudentAddress ne peut être sauvé sans y attacher un objet d'entité étudiant. Cela rend nécessaire une extrémité.

Quand entité StudentAddress ne suivent pas les conventions: Maintenant, nous allons prendre un exemple d'entité StudentAddress où il ne suit pas la convention de clé primaire à savoir avoir un autre nom de propriété Id que Id. Considérez les entités suivantes étudiants et StudentAddress.

public class Student
{
    public Student() { }

    public int StudentId { get; set; }
    public string StudentName { get; set; }

    public virtual StudentAddress Address { get; set; }

}

public class StudentAddress 
{
    public int StudentId { get; set; }

    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public int Zipcode { get; set; }
    public string State { get; set; }
    public string Country { get; set; }

    public virtual Student Student { get; set; }
}

Alors maintenant, nous avons besoin de configurer la propriété de StudentID de StudentAddress pour PrimaryKey de StudentAddress ainsi que ForeignKey comme indiqué ci-dessous.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // Configure StudentId as PK for StudentAddress
    modelBuilder.Entity<StudentAddress>()
        .HasKey(e => e.StudentId);

    // Configure StudentId as FK for StudentAddress
    modelBuilder.Entity<Student>()
                .HasOptional(s => s.Address) 
                .WithRequired(ad => ad.Student); 

}

Configurer relation One-to-One en utilisant l'API Courant: Nous pouvons configurer un à une relation entre les entités utilisant l'API Fluent où les deux extrémités sont nécessaires, ce qui signifie objet entité de l'élève doit comprendre objet entité StudentAddress et entité StudentAddress doit inclure objet entité étudiant afin de l'enregistrer.

Note: Relation-to-one est techniquement impossible dans MS SQL Server. Il sera toujours un à zéro ou un. EF forme One-to-One relations sur les entités non DB.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // Configure StudentId as PK for StudentAddress
    modelBuilder.Entity<StudentAddress>()
        .HasKey(e => e.StudentId);

    // Configure StudentId as FK for StudentAddress
    modelBuilder.Entity<Student>()
                .HasRequired(s => s.Address) 
                .WithRequiredPrincipal(ad => ad.Student); 

}

Dans le HasRequired (s => s.Address) exemple ci-dessus, modelBuilder.Entity (). Rend la propriété d'adresse de StudentAddress est nécessaire. .WithRequiredPrincipal (ad => ad.Student) rend la propriété des étudiants de l'entité StudentAddress au besoin. Ainsi, il configure les deux extrémités nécessaires. Alors maintenant, lorsque vous essayez d'enregistrer une entité étudiant sans adresse ou entité StudentAddress sans étudiant, il lancera une exception.

Référence: http: //www.entityframeworktutorial.net/code-first/configure-one-to-one-relationship-in-code-first.aspx

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top