3

真的很小的事情,但它让我有点烦恼,所以我想我会问。我有 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 配合得很好。

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

此外,很高兴探索和理解我可以非常愉快地开发应用程序的方法,同时减少思考我将如何坚持这一点的需要,或者这是否会尽可能地与实体框架配合使用。

4

1 回答 1

3

我不知道有任何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属性(来自这里的解决方案):

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");
于 2013-04-21T22:21:59.160 回答