Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 在IQueryable的Select中调用DTO转换器_.net_Linq_Entity Framework_Iqueryable_Dto - Fatal编程技术网

.net 在IQueryable的Select中调用DTO转换器

.net 在IQueryable的Select中调用DTO转换器,.net,linq,entity-framework,iqueryable,dto,.net,Linq,Entity Framework,Iqueryable,Dto,我使用以下代码通过存储库查询EntityContext并将其映射到DTO: public class QueryQuestionsConsumer : IConsumerOf<QueryQuestionsRequest> { public void Consume(QueryQuestionsRequest request) { var repo = IoC.Resolve<IUnitOfWork>().CreateRepository&l

我使用以下代码通过存储库查询EntityContext并将其映射到DTO:

public class QueryQuestionsConsumer : IConsumerOf<QueryQuestionsRequest>
{
    public void Consume(QueryQuestionsRequest request)
    {
        var repo = IoC.Resolve<IUnitOfWork>().CreateRepository<Question>();
        var filter = FilterTranslator.CreateFilterExpression<Question>(request.Filters);
        var questions = repo
            .GetAll()
            .Where(filter)

        Result = questions.Select(question => QuestionTranslator.ToDTO(question)).ToArray()
    }

}
这显然会失败,因为ToDTO不是EntityFramework提供程序中可识别的函数。我可以使用对象初始值设定项创建DTO对象,但我想将其委托给另一个类

在这种情况下你会怎么做

更新:
另外,我不想用一个完整的问题对象来做这件事。我想依靠提供者创建DTO对象的能力。

您可以将其转换为可枚举,然后在本地进行转换:

Result = questions.AsEnumerable()
                  .Select(question => QuestionTranslator.ToDTO(question)).ToArray()

这将导致查询被转换为本地可枚举项,在这里它可以安全地通过您的QuestionTranslator传递。

除了使用questions.AsEnumerable.Select。。。要强制EF检索完整记录,然后将其映射到客户端,可以使ToDTO方法返回表达式:

Expression<Func<Question, QuestionDTO>> ToDTO()
{
    Expression<Func<Question, QuestionDTO>> exp =
        question => new QuestionDTO { ... };
    return exp;
}

有一个很棒的博客系列介绍了如何在不强制计算查询的情况下实现这种功能。它基本上依赖于实现IQueryProvider。这不是一个简单的任务,下面的链接给出了构建一个简单任务的一个很好的案例研究

我使用AutoMapper从实体映射到DTO,因为如果您为问题创建映射,它将自动知道如何映射IEnumerable

在一条语句中同时执行查询和映射的问题是,当发生不好的事情时,它往往会导致数据映射程序抛出难以破译的错误,很难判断问题是在查询执行中还是在映射中

我发现通过执行.ToList/.AsEnumerable等操作触发查询,然后将该变量传递给映射器要容易得多。这使异常在出现问题时变得非常清楚,从而明确问题是在查询中还是在映射中

请参阅以下帖子:

当您使用它时,您将看到如下查询:

        Result = questions.Project().To<QuestionDto>().ToArray()

如果使用NHibernate/EF,则应在服务器上执行发送到DB的查询将仅具有投影属性。对于已在内存中读取的对象,仍应正常工作。LINQ To objects。

谢谢。因为你的回答,我觉得有必要更新这个问题。谢谢你的尝试。简单快速。无法要求更多。如果您的可查询项尚未计算,这可能会导致不支持实例化新对象的提供程序出现异常。看起来我应该更加注意谢谢指针。当然很强大,但我已经有了一个提供者,比如EF。AutoMapper是否与表达式一起工作,就像迭戈建议的那样?非常有用的提示。正如评论中所指出的,这不是一个完整的解决方案,但很有效。谢谢。我要强调的是,如果使用NHibernate/EF发送到DB的查询将只具有投影属性,那么这应该发生在服务器上。