Tome un ejemplo de las siguientes entidades Student y StudentAddress.
configurar uno-a-cero-o-uno 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, entidad StudentAddress no sigue el convención para PK, es decir, un nombre diferente para la propiedad Id, entonces también debe configurarlo para PK. Considere la siguiente entidad StudentAddress que tiene el nombre de propiedad StudentId 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 de StudentId como clave y ForeignKey. Esto hará que la propiedad StudentId en la entidad StudentAddress como PK y FK ambas.
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. Solo necesitamos configurar la entidad StudentAddress donde StudentAddressId debe ser ForeignKey.
El siguiente ejemplo establece una relación uno a cero o una relación entre Student y StudentAddress usando Fluent API.
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 utilizando el método HasOptional() 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). Luego, el método WithRequired() configura la entidad StudentAddress y crea la propiedad de navegación Student de StudentAddress según sea necesario (se requiere al guardar la entidad StudentAddress. Lanzará una excepción cuando la entidad StudentAddress esté guardando sin la propiedad de navegación del Estudiante). Esto hará que StudentAddressId también sea ForeignKey.
Por lo tanto, puede configurar una relación uno a cero entre dos entidades donde la entidad Student se puede guardar sin adjuntar el objeto StudentAddress pero la entidad StudentAddress no se puede guardar sin adjuntar un objeto de entidad Student. Esto hace que se requiera un extremo.
Cuando entidad StudentAddress no siguen las convenciones:
Ahora, vamos a dar un ejemplo de entidad StudentAddress donde no se sigue la convención clave primaria es decir, tener diferentes Id nombre de la propiedad de Id. Considere las siguientes entidades de Student 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 relación uno-a-uno entre entidades usando API Fluido donde se requieren los dos extremos, es decir, objeto de entidad estudiante debe incluir entidad StudentAddress La entidad object y StudentAddress debe incluir el objeto de la entidad Student para guardarlo.
Nota: La relación uno-a-uno no es técnicamente posible en MS SQL Server. Siempre será uno a cero o uno. EF forma relaciones uno-a-uno en entidades que no están en 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);
}
En el ejemplo anterior, modelBuilder.Entity(). HasRequired (s => s.Address) hace que se requiere la propiedad Dirección de StudentAddress. .WithRequiredPrincipal (ad => ad.Student) crea la propiedad del Estudiante de la entidad StudentAddress según sea necesario. Por lo tanto, configura ambos extremos requeridos. Así que ahora, cuando intentes guardar la entidad Student sin dirección o entidad StudentAddress sin Estudiante, arrojará una excepción.
Referencia: http://www.entityframeworktutorial.net/code-first/configure-one-to-one-relationship-in-code-first.aspx
¿Esto funciona para usted? No puedo hacer que funcione. No estoy generando la base de datos automáticamente ya que tengo tablas existentes. Mi tabla de perfil tiene Id como PK y FK (ya que la relación es 1: 1). Supongo que esto es lo mismo que tú. Si intento ejecutar su código, aparece un error: Nombre de columna inválido 'Profile_Id'. Si agrego esa columna al usuario (no es que la quiera allí), se devuelve el usuario pero el perfil es nulo. El SQL generado es:. SELECT [Extent1] [Id] AS [Id], [Extent1] [nombre de usuario] AS [nombre de usuario], [Extent1] [profile_id] AS [profile_id] DE [dbo.. ]. [Usuarios] AS [Extensión1] ¿Alguna idea? –
hmm. En la segunda inspección, parece que funciona bien en sqlce4, pero no en SQL server 2010 a menos que me falta algo. –
@ zaph0d - Si desea acceder a una propiedad que es "otra entidad", debe "incluirla". La forma de hacerlo sería 'context.Users.Include (" Profile ")'. El perfil es una "propiedad de navegación" que requerirá un JOIN en SQL. He editado mi publicación con la información adicional que olvidé para el perfil. – TheCloudlessSky