I use DB first approach
I have 3 tables with "Order" column (client order of records). I want to create similar logic to reorder in my .NET application, so, I want to work with the base class. I have created the following structure:

but project can't be compiled, column Order is not mapped for each 3 tables and I don't see a way to map it:

How to say, that Order column should be mapped to property Order of parent class?
UPDATED:
Otherwise I have to create similar methods like:
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();
}
I would like to have one method and pass objects of base class as parameters
If I understand you well, there is no table for OrderBase. This means that this is a Table-per-Concrete-Type (TPC) mapping. This link shows that with code-first, it's not hard to map TPC.
Database-first and TPC, however, don't play nice together. You have to edit the EDMX to get this done.
I did it with two of your classes. Currently, in the CS mapping content section of your EDMX you'll find something like this:
<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>
This tells which columns are mapped to which properties. As you see, Order is missing. But you can add them manually, and EF will be happy and the EDMX can still be opened in the designer:
<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>
HOWEVER: when you update the model from the database, the modifications will be gone. You'll have to add them again each time you do this. If you can, I'd strongly recommend you to port the code to code-first.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With