17

受到希望能够在 EF 查询中使用枚举的启发,我正在考虑将 ExpressionVisitor 添加到我的存储库中,该存储库将采用传入的标准/规范标准并重写它们以使用相应的持久化 int 属性。

我一直在我的(代码优先)实体中使用以下值后缀模式:

public class User : IEntity
{
    public long ID { get; set; }

    internal int MemberStatusValue { get; set; }

    public MemberStatus MemberStatus 
    {
        get { return (MemberStatus) MemberStatusValue; }
        set { MemberStatusValue = (int) value; }
    }
}

并使用以下命令将其映射到数据库:

internal class UserMapping : AbstractMappingProvider<User>
{
    public override void DefineModel( DbModelBuilder modelBuilder )
    {
        // adds ToTable and other general mappings
        base.DefineModel( modelBuilder );

        Map.Property( e => e.MemberStatusValue ).HasColumnName( "MemberStatus" );
    }
}

在我的存储库中,我有以下方法:

public IQueryable<T> Query( Expression<Func<T, bool>> filter, params string[] children )
{
    if( children == null || children.Length == 0 )
    {
        return Objects.Where( filter );
    }
    DbQuery<T> query = children.Aggregate<string, DbQuery<T>>( Objects, ( current, child ) => current.Include( child ) );
    return filter != null ? query.Where( filter ) : query;
}

我想在此方法中添加一个方法调用来重写过滤器表达式,将所有对 MemberStatus 属性的引用替换为对 MemberStatusValue 的引用。

我想这将是一个解决方案,涉及类似于在这个 SO post 中看到的内容,但我不确定如何从想法到实现。

如果您可以就添加此功能的潜在性能影响提供任何建议,我们也将不胜感激。

4

1 回答 1

1

我不确定这是否正是您所追求的,但我发现以类似但略有不同的方式处理枚举更简单。也就是说,我有两个属性,就像你一样,但我的 int 属性是公共的,并且是数据库持久的;然后我有另一个公共“包装器”属性,它通过从/到所需枚举类型的强制转换来获取/设置 int 属性值,这是应用程序的其余部分实际使用的。

结果,我不必摆弄模型;EF 可以很好地理解并保留 int 属性,而应用程序的其余部分可以与 enum 类型进行良好的交互。我唯一不喜欢我的方法的一点是,我必须在我试图查询的任何枚举值上使用一堆强制转换来编写我的 LINQ 语句,以将其转换为 int 以匹配实际持续存在的字段。然而,这是一个很小的价格,我想向您推荐它,因为在我看来,您正在使用一个字符串来生成您的查询,它放弃了 LINQ 提供的所有类型安全、Intellisense 等。

最后,如果您有兴趣了解如何使用 EF 5 中的新枚举功能(如果您想试用,现在可以下载测试版),请查看以下内容:

http://msdn.microsoft.com/en-us/hh859576

于 2012-06-08T12:59:41.507 回答