在实体框架中有一种更清晰的方法将对象类型转换为字符串表示以进行存储吗?

时间:2013-04-21 20:05:27

标签: entity-framework entity-framework-5

非常小的事情,但它让我略微烦恼,所以我想我会问。我有POCO实体设置,我正在使用代码优先实体框架。

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; }
}

正如您在代码中看到的那样,我想实际使用Type对象,但为了存储它,我最终添加了一个TypeString属性。通过DbModelBuilder我然后隐藏Type属性。

    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);
    }

我只是想知道是否有一种定义自定义属性映射的方法,而不必将该额外属性添加到我的实体。

更新

我在这些背后的理由实际上是我只想让开发人员通过登录配置一些简单设置的快速简便的方法,而且它已经很晚了,这似乎是一个允许多个设置的快速解决方案各种类型。

我想如果我想要一些强类型设置,我可能会看一下如下设置的通用实现:

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

    public T Value { get; set; }
}

虽然我不相信这会对Entity Framework起到很好的作用。

在某种程度上,虽然我对一些应用程序也很好奇但我有多个客户或利益相关者,每个客户或利益相关者都可以请求稍微不同的验证规则因此,我们通常为每个客户端或客户端集合实现和接口并创建实现。为了能够更轻松地添加客户端并自定义规则,我们存储了为每个客户端创建的接口实现。因此,持久的类型信息在这些情况下非常有用。

同样很高兴只是探索和理解我可以非常愉快地开发应用程序的方式,同时减少思考我将如何坚持这一点的需要,或者这将尽可能地与Entity Framework一起发挥作用。< / p>

1 个答案:

答案 0 :(得分:2)

我不知道有任何方法直接坚持Type,但这可能会有所改善:

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

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

然后你只需要映射受保护的_TypeString属性(来自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);
    }

然后,在ModelBuilder

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