Reputation: 1034
Following this documentation, I am trying to create some entities with properties of an owned type:
[Owned]
public class StreetAddress
{
public string Street { get; set; }
public string City { get; set; }
}
public class Order
{
public int Id { get; set; }
public StreetAddress BillingAddress { get; set; }
public StreetAddress ShippingAddress { get; set; }
}
By convention, EF will create the following properties in the entity Order:
BillingAddress_Street
BillingAddress_City
ShippingAddress_Street
ShippingAddress_City
I know that there is a way to rename the columns:
modelBuilder.Entity<Order>().OwnsOne(
o => o.ShippingAddress,
sa =>
{
sa.Property(p => p.Street).HasColumnName("ShipsToStreet");
sa.Property(p => p.City).HasColumnName("ShipsToCity");
});
however, this means that I would need to use this for every property that will be generated. In my opinion, this is exactly what I wanted to avoid by using the owned types in the first place.
What I would like to do, is to create a custom convention, however, maybe using the model builder and explicitly telling him how to name those properties getting rid of the underscore and so on.
I have tried dvelving into the modelBuilder properties, trying to get all of all entities of that owned type, but that does not seem to work.
Is there a way to solve this?
Upvotes: 1
Views: 1028
Reputation: 1034
So I could not sleep and went back to trying, and was able to solve it:
var ownedTypes = modelBuilder.Model.GetEntityTypes().Where(e => e.IsOwned());
foreach (var type in ownedTypes)
{
foreach (var prop in type.GetProperties())
{
var entityName = type.DefiningEntityType.Name;
var ownedType = type.ClrType;
var navigationName = type.DefiningNavigationName;
var propertyName = prop.Name;
var newColumnName = $"{navigationName}{propertyName}";
var primaryKeyName = modelBuilder.Model.GetEntityTypes().SingleOrDefault(e => e.Name == entityName)?.GetProperties().SingleOrDefault(p => p.IsPrimaryKey())?.Name;
if (string.IsNullOrWhiteSpace(primaryKeyName) || propertyName != primaryKeyName)
{
modelBuilder.Entity(entityName).OwnsOne(ownedType, navigationName, sa =>
{
sa.Property(propertyName).HasColumnName(newColumnName);
});
}
}
}
I would still be glad if you could point me to a better, cleaner solution, should there be one. Or maybe there are some issues here in my code.
Upvotes: 2