Estoy tratando de seguir DDD usando EF Core y en mi modelo tengo lo siguiente:
private List<TeamPerson> _personLinks; public IReadOnlyCollection<TeamPerson> PersonLinks => _personLinks?.ToList().AsReadOnly(); public IReadOnlyCollection<Person> Members => _personLinks?.Select(l => l.Person).ToList().AsReadOnly();Quiero resumir la relación entre los modelos de Equipo y Persona. Debo decir de inmediato que hay un mapeo para el modelo Person y funciona.
Pero si especifico el modo de acceso a la propiedad:
builder.HasMany(e => e.PersonLinks) .WithOne(e => e.Team) .HasForeignKey(e => e.TeamId) .Metadata.PrincipalToDependent.SetPropertyAccessMode(PropertyAccessMode.Field); builder.HasMany(e => e.TeamLinks) .WithOne(e => e.Person) .HasForeignKey(e => e.PersonId) .Metadata.PrincipalToDependent.SetPropertyAccessMode(PropertyAccessMode.Field); Y si trato de obtener dbContext.Teams.Include(t => t.PersonLinks).ThenInclude(t => t.Person) , obtengo un error: "...La columna PersonId1 no existe... ", tengo esto para el mapeo del modelo TeamPerson:
builder.Property(e => e.PersonId).IsRequired().HasColumnName("person_id");¿Cuál es mi error o hay alguna otra forma de llegar a la encapsulación de la colección aquí?
Creo que debe configurar una relación de uno a muchos entre Person y PersonLinks, así como entre Team y PersonLinks para lograr la relación de muchos a muchos.
builder.Entity<PersonLink>() .HasKey(personLink => new { personLink.TeamId, personLink.PersonId }); builder.Entity<PersonLink>() .HasOne<Team>(personLink => personLink.Team) .WithMany(team => team.PersonLinks) .HasForeignKey(personLink => personLink.TeamId); builder.Entity<PersonLink>() .HasOne<Person>(personLink => personLink.Person) .WithMany(person => person.PersonLinks) .HasForeignKey(personLink => personLink.PersonId);Por supuesto, esto solo funcionará si su clase PersonLink se parece a esto:
public class PersonLink { public int PersonId { get; set; } public Person Person { get; set; } public int TeamId { get; set; } public Team Team { get; set; } }Para los tipos de datos de identificación, asumí un int simple que podría ser una cadena o GUID (o incluso algún tipo personalizado en su código), pero creo que esto no es tan importante aquí.
Nota: No pude resistirme a cambiar el nombre de PersonLinks a PersonLink , me parece más natural porque, desde mi punto de vista, la clase representa un vínculo de una persona entre el Equipo y la Persona. Además, sé que de alguna manera es una convención usar nombres de parámetros abreviados para expresiones lambda, pero creo que, especialmente en este caso, es más fácil de leer en lugar de usar p (para Person) y pl (para PersonLink), tal vez es solo una cuestión. de gusto en este caso...