【问题标题】:Using a Query Object In A C# Expression to Return A different type在 C# 表达式中使用查询对象返回不同的类型
【发布时间】:2018-07-23 15:22:53
【问题描述】:

我目前有一个数据对象,为了论证,我将其称为 foo...

public class Foo 
{
   public int IndexedKey { get; set;}
   public string NonIndexedData {get; set;}
}

我有一个通用存储库,我想用它来查询这个对象,但是由于对数据库的权限,我不允许进行全表扫描。因此,我的任务是创建安全的查询对象。

public class FooQuery
{
    public int IndexedKey
}

通用存储库允许任意谓词,它目前具有类似于以下的实现...

public class FooRepo : IGenericRepo<Foo>
{
    private ICollection<Foo> _allFooRecords; //Imagine this is populated

    public ICollection<Foo> GetWhere(Expression<Func<Foo, bool>> criteria)
    {
        return _allFooRecords.Where(criteria.Compile())
    }
}

我希望能够做到以下...

public class FooRepo : IGenericRepo<Foo, FooQuery>
{
    private ICollection<Foo> _allFooRecords; //Imagine this is populated

    public ICollection<Foo> GetWhere(Expression<Func<FooQuery, bool>> criteria)
    {
        return _allFooRecords.Where(criteria.Compile())
    }
}

以上内容无法编译。我知道 FooQuery 的属性肯定包含与 Foo 类的索引属性匹配的正确字段,但我不能再使用条件。编译因为它将返回一个与搜索 Foo 集合不兼容的函数。有没有办法使用上述签名进行这项工作,以及我需要对我的实现进行哪些更改才能使其正常工作。

非常感谢

【问题讨论】:

  • 看我的回答,如果有问题请告诉我,否则请标记为已解决
  • 哎呀,我知道您想做什么:FooQuery 实际上是您的视图模型,而 Foo 是您的真实实体,但您想通过基于您的视图模型的表达式查询 DB。所以你想要一个将你的视图模型映射到真实模型的解决方案,是吗?
  • 尝试返回 IQueryable 而不是 ICollection。不会解决您的问题,但可能有助于大大提高性能并且可能是问题的一部分。

标签: c# linq generics lambda expression


【解决方案1】:

您的要求是:自动将视图模型表达式Expression&lt;Func&lt;FooQuery, bool&gt;&gt; 转换为真实模型表达式Expression&lt;Func&lt;Foo, bool&gt;&gt;FooQuery 实际上是你的ViewModel,但Foo 是真实的Model

Automapper 可以做到这一点。

//wrap the translate in base class, so you don't have to do it in each repo
public class BaseRepo<TEntity, TViewMode> : IGenericRepo<TEntity, TViewMode>
{
    ....
    public IWhatever<TEntity> Where(Expression<Func<TViewMode, bool>> vmExpression)
    {
        var expression = Mapper.Map<Expression<Func<TEntity, bool>>>(vmExpression);
        return whateverDataOrQuery.Where(expression);
    }

}

完整的官方文档在这里:

表达式翻译:https://github.com/AutoMapper/AutoMapper/blob/master/docs/Expression-Translation-(UseAsDataSource).md

【讨论】:

  • 我认为他们的架构被破坏了,他们可能应该返回一个 FooQuery,并使用 automappers ProjectTo 代替,但 automapper 应该在这两种情况下都有帮助 +1
  • 是的。完整的官方文档在这里:github.com/AutoMapper/AutoMapper/blob/master/docs/…
  • 啊,我没有想到自动映射器。这听起来像是一种合理的做事方式。我承认架构需要工作,但我们还处于早期阶段,如果上述工作可行,它会让我摆脱困境。明天我会试试这个,如果它有效,我会接受答案。非常感谢。
  • 自动映射器在项目中被广泛使用。尽情享受吧。
猜你喜欢
  • 2017-03-26
  • 1970-01-01
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-22
相关资源
最近更新 更多