Skip to content

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

@adelinn

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions