【问题标题】:How do I rewrite query expressions to replace enumerations with ints?如何重写查询表达式以用整数替换枚举?
【发布时间】:2011-03-19 13:47:52
【问题描述】:

受到能够在 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 的引用。

我想这将是一个涉及类似 in this SO post 的解决方案,但我不确定如何从构思到实施。

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

【问题讨论】:

  • 看看这个帖子:bit.ly/eUOi08
  • 谢谢,看起来完全正确.. 将调查!
  • 另请注意,最新版本的 EF(六月 CTP)已原生支持枚举 - 下一个正式版本 (4.2) 将使其正式 - blogs.msdn.com/b/adonet/archive/2011/06/30/…
  • 成功了吗?是否应将以上任何内容写成答案并接受?
  • 是的,但我不会在这里发布代码。此外,EF 现在支持枚举(它只是等待正式的 4.5 框架发布)。

标签: c# entity-framework reflection expression-trees entity-framework-4.1


【解决方案1】:

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

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

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

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

【讨论】:

  • 谢谢,但你错过了一些项目的标记:我没有使用字符串,而是像你一样坚持 int。我的两个属性和映射的原因是我可以将 int 值映射到以 enum 属性命名的列,这应该可以在稍后阶段简化到 EF5 的转换。我的查询和你的一样使用 int ,但我发现必须使用强制转换很麻烦 - 特别是因为你不能在查询中强制转换枚举内联,因此必须为它声明一个变量。我正在寻找的答案应该提供代码来重写查询表达式图并进行枚举转换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-24
  • 1970-01-01
  • 2010-10-06
相关资源
最近更新 更多