【问题标题】:AutoMapper Project().To<T> and reusable lambda expressionsAutoMapper Project().To<T> 和可重用的 lambda 表达式
【发布时间】:2014-04-23 09:56:25
【问题描述】:

我在获取与 AutoMapper Project().To 扩展方法一起使用的可重用 lambda 表达式时遇到问题。我正在使用 AutoMapper 3.1.1。

我希望能够通过将 lambda 表达式定义为变量来重用它,但是在使用扩展方法时遇到了问题。

注意下面显示的代码和 lambda 表达式是简化的,我的 lambda 表达式非常复杂,我想在很多地方重用它。

这是一个要重用的 lambda 表达式:

Func<Product, bool> myLambda = x => (x.Season.Id == 3);

代码块 1 使用 Project().To 和可重用的 lambda,甚至无法编译。

var dtos =
                _unitOfWork.ProductRepository.All()
                    .Where(myLambda)
                    .Project().To<ProductGridDTO>()
                    .OrderBy(dynamicSort)
                    .Skip(skip)
                    .Take(take)
                    .ToList();

它给出以下编译错误:

错误 18

“System.Collections.Generic.IEnumerable”不包含“Project”的定义,并且找不到接受“System.Collections.Generic.IEnumerable”类型的第一个参数的扩展方法“Project”(您是否缺少using 指令还是程序集引用?)

代码块 2 使用 .Select() 和 Mapper.Map() 并编译和工作,但生成的 SQL 查询返回所有列。我想使用 Project().To 在 SQL 查询中只返回一组最小的列,从而更高效、更快。

var dtos =
                _unitOfWork.ProductRepository.All()
                    .Where(myLambda)
                    .Select(y => Mapper.Map(y, new ProductGridDTO()))
                    .OrderBy(dynamicSort)
                    .Skip(skip)
                    .Take(take)
                    .ToList();

代码块 3 使用 Project().To 和相同的 lambda,但作为内联代码。它编译和工作正常,但不允许我重用我的 lambda 表达式。

        var dtos3 =
            _unitOfWork.ProductRepository.All()
                .Where(x => (x.Season.Id == 3))
                .Project().To<ProductGridDTO>()
                .OrderBy(dynamicSort)
                .Skip(skip)
                .Take(take)
                .ToList();

有什么方法可以让 代码块 1 工作。有没有另一种方法可以定义我的 lambda 表达式来解决这个编译错误?

【问题讨论】:

    标签: c# linq lambda automapper iqueryable


    【解决方案1】:

    IQueryable 对象不能与委托一起使用,它们与Expressions 一起使用。您以相同的方式初始化它们,但您必须以不同的方式声明它。

    Expression<Func<Product, bool>> myLambda = x => (x.Season.Id == 3);
    

    试试看它是否有效。

    问题是因为你传入了一个委托,你最终使用了.Where(this version 输出一个IEnumerable,问题是.Project&lt;T&gt;() 需要一个IQueyable&lt;T&gt; 并且要得到它,你必须使用this version.Where( 你只能看到Expression&lt;Func&lt;TSource, bool&gt;&gt; 而不是Func&lt;TSource, bool&gt;

    【讨论】:

    • 感谢 Scott,我之前曾尝试过此操作,但我认为当时我的代码存在其他问题,导致其他错误。我在你的提示下又试了一次,现在效果很好。谢谢!
    猜你喜欢
    • 2011-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 2010-11-17
    相关资源
    最近更新 更多