简体   繁体   中英

Mapping from Domain Model

I have a domain model where the properties have their own domain types (which all have the "Value" Property to return their scalar values). Eg

Class FurryFrogMessage {
    public Name FurryFrogName {get; private set}
    public MaxWeight FurryFrogTopsOutAt {get; private set}
    ...
}

Class Name {
    public string Value;
    ...
}
...

Now I come to persist the objects in the domain model I am uncertain about which is the best approach to take.

I am using Entity Framework, attempting to use the domain classes with EF Fluent API to describe how the data should be mapped to database tables.

However since every property of my domain classes is a complex type, Entity Framework left to itself is setting the column names as the complex type followed by "_Value" (the property of the complex type).

eg "FurryFrogName_Value" is the name of the column whereas I want it to be "FurryFrogName"

In order to have sensible column names, I am having to specify the column name for every single property of every single class in the Fluent API.

modelBuilder.Entity<FurryFrogMessage >()
    .Property(m => m.FurryFrogName.Value)
        .HasColumnName("FurryFrogName");
modelBuilder.Entity<FurryFrogMessage >()
    .Property(m => m.FurryFrogTopsOutAt.Value)
        .HasColumnName("FurryFrogTopsOutAt");

Is there some way to customise the mapping in Entity Framework to indicate that for each property (which is a Complex Type) in my domain classes I want it to use name of the property and the Value Property of the Complex Type?

Or am I asking too much of Entity Framework?

(Or possibly should I be doing this another way?)

I would comment, but I lack reputation.

You can try using ColumnAttribute like this in entity classes:

[Column("CustomName")]
public MyType Name { get; set; }

Still some code but less.

I'm not familiar with Entity Framework, but gave it a try. After some tinkering I made an extension method that takes an expression as a parameter, extracts the first property name from the body and uses it as the column name.

Here is my implementation:

public static class EntityTypeConfigurationExtensions
{
    public static void ComplexProperty<T>(
        this EntityTypeConfiguration<T> configuration,
        Expression<Func<T, string>> expression) 
        where T : class
    {
        var columnName = expression.Body.ToString().Split('.')[1];

        configuration.Property(expression).HasColumnName(columnName);
    }
}

where T : class constraint comes from EntityTypeConfiguration .

Usage in your example:

modelBuilder.Entity<FurryFrogMessage>()
    .ComplexProperty(m => m.FurryFrogName.Value)

Also, here's link to my example based on microsofts EF tutorial: https://gist.github.com/anonymous/d59d5c71787b5604bf41e021fcc53791

It works for me with VS2017 on LocalDb. EF creates table Blogs with columns BlogId of type int and Name of type nvarchar(max).

I'm not sure what you are trying to achieve with custom object containing value instead of just using string , but I hope my answer helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM