entity-framework-4.1 - hasrequired - many to many entity framework fluent api
¿Puedo especificar una columna discriminadora con una asignación de tabla por tipo? (2)
Hice una anulación en SaveChanges para lograr algo similar. Simplemente agregué un atributo a la clase abstracta llamada Discriminador y lo configuré según el Nombre de la clase concreta cada vez que se agrega algo nuevo.
public class MyContext : DbContext
{
public override int SaveChanges()
{
foreach (var item in ChangeTracker.Entries().Where(x=>x.Entity is MyAbstractClass && x.State == EntityState.Added))
{
((MyAbstractClass)item.Entity).Descriminator = item.Entity.GetType().Name;
}
return base.SaveChanges();
}
}
Tengo una jerarquía de clases que deseo asignar a través de varias tablas utilizando Entity Framework 4.1 Code First. Es como una tabla por tipo (TPT), pero también quiero una columna discriminadora.
La jerarquía se ve algo así como:
public class Event
{
public Guid Id { get; set; }
public string Code { get; set; } // discriminator
public DateTime Date { get; set; }
}
public class Party : Event
{
public int AttendeeCount { get; set; }
}
public class BirthdayParty : Party
{
public int Age { get; set; }
}
public class WeddingParty : Party
{
public string Surname { get; set; }
}
Este es un ejemplo bastante débil, pero espero que tenga sentido. Habrá una tabla de "Eventos", una tabla de "Partes" y una tabla para cada tipo de fiesta. Sin embargo, la columna discriminadora ("Código") tendrá un valor conocido para cada tipo de evento, como "NACIMIENTO" para fiestas de cumpleaños o "BODA" para bodas.
La idea es que si busco solo fiestas de cumpleaños en una fecha determinada, EF sabría agregar Code = ''BIRTH''
a mi consulta en lugar de hacer un montón de UNIONs y JOINs para averiguar qué filas necesita.
Asigno mis clases de nivel más bajo como esto:
var bd = modelBuilder.Entity<BirthdayParty>();
bd.ToTable("BirthdayParties");
bd.Property(p => p.Age).HasColumnName("BirthdayAge");
Ahora necesito especificar el valor discriminador allí de alguna manera. He intentado esto:
modelBuilder.Entity<Event>().Map<BirthdayParty>(cfg =>
{
cfg.Requires("Code").HasValue("BIRTH");
});
... pero se queja de que no he especificado el nombre de la tabla dentro de la llamada a Map
. Así que intenté mover la llamada de ToTable
allí:
var bd = modelBuilder.Entity<BirthdayParty>();
bd.Property(p => p.Age).HasColumnName("BirthdayAge");
modelBuilder.Entity<Event>().Map<BirthdayParty>(cfg =>
{
cfg.Requires("Code").HasValue("BIRTH");
cfg.ToTable("BirthdayParties");
});
... y ahora cree que quiero una columna "Código" en la tabla "Fiestas de cumpleaños", que no es correcta. Ya le dije que la columna "Código" está en la tabla "Eventos".
¿Es esto posible? ¿Puedo combinar el uso de una columna discriminadora con una asignación de tabla por tipo?
Lamentablemente esto no es compatible. La columna discriminadora solo se puede utilizar en TPH. TPT diferencia los tipos de entidades por tablas mapeadas y siempre produce esas terribles consultas. Podría ser una buena característica, por lo que tal vez la sugerencia sobre Data UserVoice la implementaría algún día.
Actualizar
Ya hay una sugerencia en la voz del usuario para este titulado " Compatibilidad con columnas discriminadoras en la herencia TPT ".