Skip to content

Error when projecting query to custom type .Select(p => new MyDto {...}) #87

Description

@adelinn

When I run a Select and want the result to be of a specific type, like this:

persons.Query().Where(p => p.Uid == personUid).Select(p => new MyDto
    {
        PersonUid = p.Uid
    });

I get this error

System.InvalidOperationException: When called from 'VisitMemberInit', rewriting a node of type 'System.Linq.Expressions.NewExpression' must return a non-null value of the same type. Alternatively, override 'VisitMemberInit' and change it to not visit children of this type.
         at System.Linq.Expressions.ExpressionVisitor.VisitAndConvert[T](T node, String callerName)
         at System.Linq.Expressions.ExpressionVisitor.VisitMemberInit(MemberInitExpression node)
         at BccCode.Linq.Client.Evaluator.SubtreeEvaluator.Visit(Expression exp)
         at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node)
         at BccCode.Linq.Client.Evaluator.SubtreeEvaluator.Visit(Expression exp)
         at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node)
         at BccCode.Linq.Client.Evaluator.SubtreeEvaluator.Visit(Expression exp)
         at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
         at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
         at BccCode.Linq.Client.Evaluator.SubtreeEvaluator.Visit(Expression exp)
         at BccCode.Linq.Client.Evaluator.SubtreeEvaluator.Eval(Expression exp)
         at BccCode.Linq.Client.Evaluator.PartialEval(Expression expression, Func`2 fnCanBeEvaluated)
         at BccCode.Linq.Client.ApiQueryProvider.TranslateExpression(Expression expression, QueryableTypeMode expectedTypeMode)
         at BccCode.Linq.Client.ApiQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
         at BccCode.Linq.Client.QueryableAsyncExtensions.AsAsyncEnumerable[TSource](IQueryable`1 queryable, CancellationToken cancellationToken)
         at BccCode.Linq.Client.QueryableAsyncExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)

This bug encourages inefficient use of the library because the easiest path would be to materialize the response and then project it to MyDto, but that means I would request from the API all properties of the Person object when I only need a subset.

A workaround for keeping this efficient until this gets fixed would be to project this to an anonymous object, then materialize the query then project it to MyDto.

persons.Query().Where(p => p.Uid == personUid).Select(p => new
    {
        PersonUid = p.Uid
    }).ToListAsync(cancellationToken)
    .ContinueWith((task) => {
        return task.Result.Select(p => new MyDto
        {
            PersonUid = p.PersonUid
        }).ToList();
    }, cancellationToken);

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions