In Entity Framework is there a cleaner way of converting an object type to a string representation for storage?

爱⌒轻易说出口 提交于 2019-12-08 04:13:02

问题


Very minor thing really but it bugs me slightly so I thought I'd ask. I have the POCO entity Setting and I'm using a code first approach to Entity Framework.

public class Setting
{
    [Required]
    [MaxLength(128)]
    public string Name { get; set; }

    [Required]
    public Type Type { get; set; }

    //  Added to support the storing of Type in the database via Entity Framework.
    // Really would be nice to find a cleaner way but this isn't actually so bad.
    public string TypeString
    {
        get { return Type.ToString(); }
        set { Type = Type.GetType(value); }
    }

    public string Value { get; set; }
}

As you can see for use in code I'd like to actually be using the Type object but to store this I have ended up adding a TypeString property. Via the DbModelBuilder I then hide the Type property.

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder
            .Entity<Setting>()
            .HasKey(e => e.Name)
            .Property(e => e.Name)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        modelBuilder
            .Entity<Setting>()
            .Ignore(e => e.Type);
        modelBuilder
            .Entity<Setting>()
            .Property(e => e.TypeString)
            .HasColumnName("Type");

        base.OnModelCreating(modelBuilder);
    }

I just was wondering if there was a way of defining a custom property mapping instead of having to add that extra property to my entity.

UPDATE

My reasoning behind these was actually that I just wanted a quick and easy way for developers to be able to configure a few simple settings by logging in, and it was late and this seemed like a quick solution to allow for several settings of various types.

I suppose if if I wanted some strongly typed settings I'd probably look at a generic implementation of setting such as below:

public class Setting<T>
{
    [Required]
    [MaxLength(128)]
    public string Name { get; set; }

    public T Value { get; set; }
}

Though I don't believe that is something that will play nice with Entity Framework.

In part though I'm also curious as for some applications I have multiple clients or stakeholders who can each request slightly different validation rules. As such we usually implement and interface and create an implementation per clients or collections of clients. In order that we can more easily add clients and customise their rules we store which implementation of the interface to create for each client. So persisting type information has proved extremely useful in those cases.

Also it's nice to just explore and understand ways that I can quite happily develop an application whilst reducing the need to think how am I going to persist this, or is this going to play nice with Entity Framework as much as possible.


回答1:


I'm not aware of any way to persist Type directly, but this may feel a bit better:

public class Settings
{
    public Type Type
    {
        get { return Type.GetType(_TypeString); }
        set { _TypeString = value.ToString(); }
    }

    // Backing Field
    protected virtual string _TypeString { get; set; }
}

Then you just need to map the protected _TypeString property (solution from here):

public static StringPropertyConfiguration Property<T>(this EntityTypeConfiguration<T> mapper, String propertyName) where T : class
    {
        Type type = typeof(T);
        ParameterExpression arg = Expression.Parameter(type, "x");
        Expression expr = arg;

        PropertyInfo pi = type.GetProperty(propertyName,
            BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
        expr = Expression.Property(expr, pi);

        LambdaExpression lambda = Expression.Lambda(expr, arg);

        Expression<Func<T, String>> expression = (Expression<Func<T, string>>)lambda;
        return mapper.Property(expression);
    }

Then, in your ModelBuilder:

modelBuilder
        .Entity<Setting>()
        .Property("_TypeString")
        .HasColumnName("Type");


来源:https://stackoverflow.com/questions/16135642/in-entity-framework-is-there-a-cleaner-way-of-converting-an-object-type-to-a-str

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!