Pregunta

¿Cómo declarar una relación uno a uno utilizando código de Entity Framework 4 Primera (POCO)?

encontré esta pregunta (de uno a-uno relaciones en Entity Framework 4) , pero el artículo que hace referencia la respuesta no fue útil (hay una línea de código que es una relación 1-1, pero ninguna mención de cómo definirlo).

¿Fue útil?

Solución

¿Usted está buscando algo como esto?

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

Editar : Sí, yo no tenía VS frente a mí, pero es necesario añadir la siguiente línea en el UserMapping en lugar de la actual HasRequired y también añadir una propiedad ProfileId (en lugar de que Profile_Id que agregó):

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

Actualmente no creo que hay una forma de evitar esto, pero estoy seguro de que va a cambiar ya que estamos sólo en CTP4. Sería bueno si pudiera decir:

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

De esta manera no tendría que incluir una propiedad ProfileId. Tal vez hay una forma de evitar esto actualmente y sigue siendo a primera hora de la mañana para mí pensar:.)

Asimismo, recuerda a llamar .Include("Profile") si desea incluir una "propiedad de navegación".

Otros consejos

Tres métodos:

A) Declarar ambas clases con propiedades de navegación entre sí. Marque una de las mesas (la tabla dependiente) con el atributo ForeignKey en su clave primaria. infiere EF 1-a-1 de esta:

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

http://weblogs.asp.net/manavi/archive/2011/05/01/associations-in-ef-4-1-code-first- parte-5-uno-a-uno-exterior-key-associations.aspx

Yo no utilizar virtual y no debe tampoco. *

b) declarar una jerarquía de herencia con ambos nombres de las tablas indicadas explícitamente, lo que resulta en la Tabla-Per-Type y una clave principal compartida.

using System.ComponentModel.DataAnnotations;

[Table("AppUser")]
public class AppUser
{
    public int Id { get; set; }

    public string Username { get; set; }

    public OpenIdInfo OpenIdInfo { get; set; }
}

[Table("AdminUser")]      
public class AdminUser : AppUser
{
    public bool SuperAdmin { get; set; }
}

obtendrá 2 tablas: una para appuser, uno para adminuser. Adminuser es de 1: 1 con appuser y depende - lo que significa que puede eliminar un adminuser, pero si se elimina un appuser cuando un adminuser todavía está apuntando a ella, obtendrá un error de restricción Violación.

C) Hay 2 métodos medio-manera de hacer uno-a-uno en EF:

Entidad-Splitting , donde se tiene una sola clase, pero se almacena en una tabla principal, y 1 o más de uno-a-uno tablas relacionadas.

Tabla-Splitting , donde un árbol de objetos se aplana en una sola tabla. Por ejemplo, una clase con una propiedad Dirección tendría columnas para el objeto Dirección, como address_city, aplanado en una sola tabla.

* Puede incluir virtual en cualquier propiedad o EF Colecciones si quieres perezoso carga ellos. Esto puede dar lugar a bucles infinitos o cargar toda la base de datos si se pasa un objeto con propiedades de perezosos cargado a, por ejemplo, el convertidor MVC JSON o cualquier otra cosa que camina la jerarquía de objetos. El Lazy-Carga siempre se realiza de forma sincrónica, el bloqueo de la rosca, y sin previo aviso. Para resumir, la lista de las maneras en que puede congelar su código, aplicación o servidor con él es largo. Evitar el uso virtual en las clases de EF. Sí, hay un montón de ejemplos de código en Internet que lo utilizan. No, todavía no se debe utilizar.

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

Añadir el perfil virtual y el ID de usuario y yo creo que debería llegar hasta allí.

Tome un ejemplo de las siguientes entidades estudiantiles y StudentAddress.
Configurar uno a cero o uno relación utilizando 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; }
}

Cuando entidad StudentAddress no sigue las convenciones:

Si, por ejemplo, StudentAddress entidad no sigue la convención para PK es decir, nombre diferente para la propiedad Id Luego hay que configurarlo para PK también. Considere la siguiente entidad StudentAddress que se studentID nombre de la propiedad en lugar 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; }
}

En el ejemplo anterior, tenemos que configurar la propiedad StudentId como clave, así como ForeignKey. Esto hará que la propiedad StudentId en la entidad StudentAddress como PK y FK ambos.

Configurar uno a cero o-Una relación utilizando la API de Fluido:
Cuando los estudiantes y StudentAddress siguen las convenciones: entidades estudiantiles y StudentAddress siguen la convención de código de primer defecto para PrimaryKey. Por lo tanto, no es necesario configurarlos para definir sus PrimaryKeys. Tan sólo hay que configurar entidad StudentAddress donde StudentAddressId debe ser ForeignKey.

El ejemplo siguiente define de uno a cero o uno relación entre estudiante y StudentAddress usando API Fluido.

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

}

En el ejemplo anterior, la entidad Estudiante se configura mediante HasOptional () método que indica que la propiedad de navegación StudentAddress en la entidad de los estudiantes es un accesorio opcional (no se requiere cuando se guarda entidad Estudiante). Entonces, WithRequired () configura método StudentAddress entidad y marca propiedad de navegación Estudiante de StudentAddress según sea necesario (requerido al guardar entidad StudentAddress. Será una excepción cuando la entidad StudentAddress está ahorrando y sin propiedad de navegación Estudiante). Esto hará que StudentAddressId como ForeignKey también.

Por lo tanto, se puede configurar relación de uno a cero o uno entre dos entidades en las que la entidad Estudiante se pueden guardar sin asociar objeto StudentAddress a ella, pero StudentAddress entidad no se puede guardar sin asociar un objeto de entidad Estudiante. Esto hace necesario un extremo.

Cuando entidad StudentAddress no siguen las convenciones:
Ahora, tomemos un ejemplo de entidad StudentAddress donde no se sigue la convención clave primaria es decir, que tienen diferentes nombre de la propiedad de Id Id. Tenga en cuenta las siguientes entidades estudiantiles y 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; }
}

Así que ahora, tenemos que configurar la propiedad StudentId de StudentAddress para PrimaryKey de StudentAddress, así como ForeignKey como se muestra a continuación.

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

}

Configurar Uno-a-uno utilizando la API de Fluido:
Podemos configurar uno-a-uno entre las entidades que utilizan la API Fluido donde se requieren los dos extremos, es decir, objeto de entidad estudiante debe incluir StudentAddress objeto de entidad y la entidad debe incluir StudentAddress objeto de entidad estudiante con el fin de salvarlo.

Nota: Uno-a-uno no es técnicamente posible en MS SQL Server. Siempre será de uno a cero o uno. EF forma One-to-One relaciones de entidades no en base de datos.

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

}

En el ejemplo anterior, modelBuilder.Entity (). HasRequired (s => s.Address) hace que se requiere propiedad Dirección de StudentAddress. .WithRequiredPrincipal (ad => ad.Student) hace que la propiedad de la entidad StudentAddress estudiante según sea necesario. Por lo tanto, configura ambos extremos requeridos. Así que ahora, cuando intenta guardar entidad estudiante sin dirección o entidad sin StudentAddress Estudiante, se lanzará una excepción.

Referencia: http: //www.entityframeworktutorial.net/code-first/configure-one-to-one-relationship-in-code-first.aspx

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top