sql - tph - hierarchy entity framework
Marco de la entidad y herencia (1)
Si lo entiendo bien, no hay una tabla para OrderBase
. Esto significa que se trata de una asignación Table-per-Concrete-Type (TPC). Este enlace muestra que con el código primero, no es difícil mapear TPC.
Database-first y TPC, sin embargo, no funcionan bien juntos. Tienes que editar el EDMX para hacer esto.
Lo hice con dos de tus clases. Actualmente, en la sección de contenido de mapeo CS de su EDMX encontrará algo como esto:
<EntitySetMapping Name="OrderBases">
<EntityTypeMapping TypeName="IsTypeOf(TPCModel.EcortGroup)">
<MappingFragment StoreEntitySet="EcortGroup">
<ScalarProperty Name="GroupName" ColumnName="GroupName" />
<ScalarProperty Name="ID" ColumnName="ID" />
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="IsTypeOf(TPCModel.EscortItem)">
<MappingFragment StoreEntitySet="EscortItem">
<ScalarProperty Name="Escort" ColumnName="Escort" />
<ScalarProperty Name="EcortGroup_ID" ColumnName="EcortGroup_ID" />
<ScalarProperty Name="ID" ColumnName="ID" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
Esto indica qué columnas se asignan a qué propiedades. Como puede ver, Order
is missing. Pero puede agregarlos manualmente, y EF estará feliz y el EDMX aún se puede abrir en el diseñador:
<EntityTypeMapping TypeName="IsTypeOf(TPCModel.EcortGroup)">
<MappingFragment StoreEntitySet="EcortGroup">
<ScalarProperty Name="GroupName" ColumnName="GroupName" />
<ScalarProperty Name="ID" ColumnName="ID" />
<ScalarProperty Name="Order" ColumnName="Order" />
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="IsTypeOf(TPCModel.EscortItem)">
<MappingFragment StoreEntitySet="EscortItem">
<ScalarProperty Name="Escort" ColumnName="Escort" />
<ScalarProperty Name="EcortGroup_ID" ColumnName="EcortGroup_ID" />
<ScalarProperty Name="ID" ColumnName="ID" />
<ScalarProperty Name="Order" ColumnName="Order" />
</MappingFragment>
</EntityTypeMapping>
SIN EMBARGO : cuando actualiza el modelo de la base de datos, las modificaciones desaparecerán. Tendrás que volver a agregarlos cada vez que hagas esto. Si puede, le recomiendo encarecidamente que transfiera el código al código primero.
Yo uso DB primer enfoque
Tengo 3 tablas con la columna "Orden" (orden de los registros del cliente). Quiero crear una lógica similar para reordenar en mi aplicación .NET, entonces, quiero trabajar con la clase base. He creado la siguiente estructura:
pero el proyecto no se puede compilar, el orden de la columna no está asignado para cada 3 tablas y no veo una forma de asignarlo:
¿Cómo decir que esa columna Orden debe asignarse a la propiedad Orden de la clase padre?
ACTUALIZADO:
De lo contrario, tengo que crear métodos similares, como:
public interface IOrder
{
int Order { get; set; }
}
public partial class EscortDescription : IOrder
{
}
public partial class EscortGroup : IOrder
{
}
public partial class EscortItem : IOrder
{
}
private async Task ReorderEscortAsync(Infrastructure.IOrder item1, Infrastructure.IOrder item2)
{
Random rnd = new Random();
if (item1 == null)
throw new ArgumentNullException("firstItem");
if (item2 == null)
throw new ArgumentNullException("secondItem");
int tmpItem1Order = item1.Order;
int tmpItem2Order = item2.Order;
item1.Order = rnd.Next(int.MinValue, -1);
item2.Order = rnd.Next(int.MinValue, -1);
_db.SaveChanges();
item1.Order = tmpItem2Order;
item2.Order = tmpItem1Order;
await _db.SaveChangesAsync();
}
public async Task EscortGroupItemUpAsync(int ItemID)
{
var firstItem = (from i in _db.EscortItems where i.ID == ItemID select i).FirstOrDefault();
if (firstItem == null)
throw new Domain.RecordNotFoundException<int>(ItemID, "ID", "EscortItems");
var secondItem = (from i in _db.EscortItems where i.Order < firstItem.Order orderby i.Order descending select i).FirstOrDefault();
if (secondItem != null)
await ReorderEscortAsync(firstItem, secondItem);
else
throw new FirstRecordException();
}
public async Task EscortGroupItemDownAsync(int ItemID)
{
var secondItem = (from i in _db.EscortItems where i.ID == ItemID select i).FirstOrDefault();
if (secondItem == null)
throw new Domain.RecordNotFoundException<int>(ItemID, "ID", "EscortItems");
var firstItem = (from i in _db.EscortItems where i.Order > secondItem.Order orderby i.Order ascending select i).FirstOrDefault();
if (firstItem != null)
await ReorderEscortAsync(firstItem, secondItem);
else
throw new LastRecordException();
}
public async Task EscortGroupUpAsync(int ItemID)
{
var firstItem = (from i in _db.EscortGroups where i.ID == ItemID select i).FirstOrDefault();
if (firstItem == null)
throw new Domain.RecordNotFoundException<int>(ItemID, "ID", "EscortGroups");
var secondItem = (from i in _db.EscortGroups where i.Order < firstItem.Order orderby i.Order descending select i).FirstOrDefault();
if (secondItem != null)
await ReorderEscortAsync(firstItem, secondItem);
else
throw new FirstRecordException();
}
public async Task EscortGroupDownAsync(int ItemID)
{
var secondItem = (from i in _db.EscortGroups where i.ID == ItemID select i).FirstOrDefault();
if (secondItem == null)
throw new Domain.RecordNotFoundException<int>(ItemID, "ID", "EscortGroups");
var firstItem = (from i in _db.EscortGroups where i.Order > secondItem.Order orderby i.Order ascending select i).FirstOrDefault();
if (firstItem != null)
await ReorderEscortAsync(firstItem, secondItem);
else
throw new LastRecordException();
}
Me gustaría tener un método y pasar objetos de la clase base como parámetros