Skip to content

System.Reflection.TargetInvocationException: 'Exception has been thrown by the target of an invocation.' #3799

Description

@darko1979

This error appeared after installing linq2db v4.3.0.
I created an example to demonstrate the issue.

Here is the database schema:

DROP TABLE IF EXISTS items;
CREATE TABLE IF NOT EXISTS items
(
  id INT NOT NULL,
  parent_id INT,
  name VARCHAR(100) NOT NULL,
  CONSTRAINT items_pk PRIMARY KEY (id)
);
ALTER TABLE ONLY items ADD CONSTRAINT fk_items_parent_id FOREIGN KEY (parent_id) REFERENCES public.items(id);
INSERT INTO items(id,parent_id,name) VALUES 
  (1, null, 'root'),
  (2, 1, 'child 1'),
  (3, 2, 'child 1.1'),
  (4, 2, 'child 1.2'),
  (5, 1, 'child 2'),
  (6, 5, 'child 2.1'),
  (7, 5, 'child 2.1');

and here is the console sample app:

using LinqToDB;
using LinqToDB.Data;
using System.Text.Json;
using System.Text.Json.Serialization;
using LinqToDB.Mapping;

namespace test
{
    [Table(Schema = "public", Name = "items")]
    public partial class Item
    {
        [Column("id", DataType = LinqToDB.DataType.Int32, Precision = 32, Scale = 0), PrimaryKey, NotNull] public int Id { get; set; } // integer
        [Column("parent_id", DataType = LinqToDB.DataType.Int32, Precision = 32, Scale = 0), Nullable] public int? ParentId { get; set; } // integer
        [Column("name", DataType = LinqToDB.DataType.NVarChar, Length = 100), NotNull] public string Name { get; set; } // character varying(100)

        [Association(ThisKey = "Id", OtherKey = "ParentId", CanBeNull = true)]
        public IEnumerable<Item> Children { get; set; }
    }

    public sealed class FirstChildModel
    {
        public string Name { get; set; }
        public IEnumerable<string> ChildrenNames { get; set; }

        internal static System.Linq.Expressions.Expression<Func<Item, FirstChildModel>> Selector = item => new FirstChildModel
        {
            Name = item.Name,
            ChildrenNames = item.Children.AsQueryable().Select(x => x.Name).ToList(),
        };
    }

    public sealed class ItemModel
    {
        public string Name { get; set; }
        public FirstChildModel FirstChild { get; set; }

        internal static System.Linq.Expressions.Expression<Func<Item, ItemModel>> Selector = item => new ItemModel
        {
            Name = item.Name,
            FirstChild = item.Children.AsQueryable().Select(FirstChildModel.Selector).FirstOrDefault(),
        };
    }

    class Program
    {
        static async Task Main(string[] args)
        {
            var connectionString = "Server=localhost;Port=5432;Database=test;User Id=postgres;Password=postgres;";
            var options = new JsonSerializerOptions { Converters = { new JsonStringEnumConverter() }, WriteIndented = true };
            DataConnection.TurnTraceSwitchOn(System.Diagnostics.TraceLevel.Verbose);
            DataConnection.WriteTraceLine = (s1, s2, level) => Console.WriteLine($"{level}: {s1}, {s2}");
            var db = new DataConnection(ProviderName.PostgreSQL, connectionString);

            var result = await db.GetTable<Item>().Select(ItemModel.Selector).ToListAsync();                
            Console.WriteLine(JsonSerializer.Serialize(result, options));

            Console.WriteLine("Done!");
            Console.ReadKey();
        }
    }
}

And here is the stack trace:

System.Reflection.TargetInvocationException
  HResult=0x80131604
  Message=Exception has been thrown by the target of an invocation.
  Source=System.Private.CoreLib
  StackTrace:
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at LinqToDB.Linq.Builder.EagerLoading.GenerateDetailsExpression(IBuildContext context, MappingSchema mappingSchema, Expression expression)
   at LinqToDB.Linq.Builder.ExpressionBuilder.GetMultipleQueryExpression(IBuildContext context, MappingSchema mappingSchema, Expression expression, HashSet`1 parameters, Boolean& isLazy)
   at LinqToDB.Linq.Builder.ExpressionBuilder.BuildMultipleQuery(IBuildContext context, Expression expression, Boolean enforceServerSide)
   at LinqToDB.Linq.Builder.ExpressionBuilder.<>c.<BuildExpression>b__93_0(ValueTuple`4 context, Expression expr)
   at LinqToDB.Expressions.TransformInfoVisitor`1.Transform(Expression expr)
   at LinqToDB.Expressions.TransformInfoVisitor`1.Transform[T](IList`1 source)
   at LinqToDB.Expressions.TransformInfoVisitor`1.Transform(Expression expr)
   at LinqToDB.Linq.Builder.ExpressionBuilder.BuildExpression(IBuildContext context, Expression expression, Boolean enforceServerSide, String alias)
   at LinqToDB.Linq.Builder.ExpressionBuilder.CorrectConditional(IBuildContext context, Expression expr, Boolean enforceServerSide, String alias)
   at LinqToDB.Linq.Builder.ExpressionBuilder.ConvertAssignmentArgument(IBuildContext context, Expression expr, MemberInfo memberInfo, Boolean enforceServerSide, String alias)
   at LinqToDB.Linq.Builder.ExpressionBuilder.<>c.<BuildExpression>b__93_0(ValueTuple`4 context, Expression expr)
   at LinqToDB.Expressions.TransformInfoVisitor`1.Transform(Expression expr)
   at LinqToDB.Linq.Builder.ExpressionBuilder.BuildExpression(IBuildContext context, Expression expression, Boolean enforceServerSide, String alias)
   at LinqToDB.Linq.Builder.SelectContext.BuildExpression(Expression expression, Int32 level, Boolean enforceServerSide)
   at LinqToDB.Linq.Builder.FirstSingleBuilder.FirstSingleContext.BuildExpression(Expression expression, Int32 level, Boolean enforceServerSide)
   at LinqToDB.Linq.Builder.ExpressionBuilder.GetSubQueryExpression(IBuildContext context, MethodCallExpression expr, Boolean enforceServerSide, String alias)
   at LinqToDB.Linq.Builder.ExpressionBuilder.<>c.<BuildExpression>b__93_0(ValueTuple`4 context, Expression expr)
   at LinqToDB.Expressions.TransformInfoVisitor`1.Transform(Expression expr)
   at LinqToDB.Linq.Builder.ExpressionBuilder.BuildExpression(IBuildContext context, Expression expression, Boolean enforceServerSide, String alias)
   at LinqToDB.Linq.Builder.ExpressionBuilder.CorrectConditional(IBuildContext context, Expression expr, Boolean enforceServerSide, String alias)
   at LinqToDB.Linq.Builder.ExpressionBuilder.ConvertAssignmentArgument(IBuildContext context, Expression expr, MemberInfo memberInfo, Boolean enforceServerSide, String alias)
   at LinqToDB.Linq.Builder.ExpressionBuilder.<>c.<BuildExpression>b__93_0(ValueTuple`4 context, Expression expr)
   at LinqToDB.Expressions.TransformInfoVisitor`1.Transform(Expression expr)
   at LinqToDB.Linq.Builder.ExpressionBuilder.BuildExpression(IBuildContext context, Expression expression, Boolean enforceServerSide, String alias)
   at LinqToDB.Linq.Builder.SelectContext.BuildExpression(Expression expression, Int32 level, Boolean enforceServerSide)
   at LinqToDB.Linq.Builder.SelectContext.BuildQuery[T](Query`1 query, ParameterExpression queryParameter)
   at LinqToDB.Linq.Builder.ExpressionBuilder.Build[T]()
   at LinqToDB.Linq.Query`1.CreateQuery(ExpressionTreeOptimizationContext optimizationContext, ParametersContext parametersContext, IDataContext dataContext, Expression expr)
   at LinqToDB.Linq.Query`1.GetQuery(IDataContext dataContext, Expression& expr, Boolean& dependsOnParameters)
   at LinqToDB.Linq.ExpressionQuery`1.GetQuery(Expression& expression, Boolean cache, Boolean& dependsOnParameters)
   at LinqToDB.Linq.ExpressionQuery`1.<GetForEachAsync>d__19.MoveNext()
   at LinqToDB.AsyncExtensions.<ToListAsync>d__8`1.MoveNext()
   at test.Program.<Main>d__0.MoveNext() in C:\temp\linq2db-test\main.cs:line 78
   at test.Program.<Main>(String[] args)

  This exception was originally thrown at this call stack:
    LinqToDB.Linq.Builder.SelectContext.GetContext(System.Linq.Expressions.Expression, int, LinqToDB.Linq.Builder.BuildInfo)
    LinqToDB.Linq.Builder.SelectContext.ProcessScalar<T, TContext>(TContext, System.Linq.Expressions.Expression, int, System.Func<TContext, LinqToDB.Linq.Builder.IBuildContext, System.Linq.Expressions.Expression, int, T>, System.Func<TContext, T>, bool)
    LinqToDB.Linq.Builder.SelectContext.GetContext(System.Linq.Expressions.Expression, int, LinqToDB.Linq.Builder.BuildInfo)
    LinqToDB.Linq.Builder.TableBuilder.BuildSequence(LinqToDB.Linq.Builder.ExpressionBuilder, LinqToDB.Linq.Builder.BuildInfo)
    LinqToDB.Linq.Builder.ExpressionBuilder.BuildSequence(LinqToDB.Linq.Builder.BuildInfo)
    LinqToDB.Linq.Builder.ExpressionBuilder.BuildSequence(LinqToDB.Linq.Builder.BuildInfo)
    LinqToDB.Linq.Builder.SelectBuilder.BuildMethodCall(LinqToDB.Linq.Builder.ExpressionBuilder, System.Linq.Expressions.MethodCallExpression, LinqToDB.Linq.Builder.BuildInfo)
    LinqToDB.Linq.Builder.ExpressionBuilder.BuildSequence(LinqToDB.Linq.Builder.BuildInfo)
    LinqToDB.Linq.Builder.SelectManyBuilder.BuildMethodCall(LinqToDB.Linq.Builder.ExpressionBuilder, System.Linq.Expressions.MethodCallExpression, LinqToDB.Linq.Builder.BuildInfo)
    LinqToDB.Linq.Builder.ExpressionBuilder.BuildSequence(LinqToDB.Linq.Builder.BuildInfo)
    ...
    [Call Stack Truncated]

Inner Exception 1:
NotImplementedException: The method or operation is not implemented.

This example works without issues using linq2db v4.2.0.
I also managed to find a solution to fix this by changing this line

FirstChild = item.Children.AsQueryable().Select(FirstChildModel.Selector).FirstOrDefault(),

to this

FirstChild = item.Children.AsQueryable().Select(FirstChildModel.Selector).AsEnumerable().FirstOrDefault(),

by adding AsEnumerable() before FirstOrDefault()

Environment details
linq2db version: 4.3.0
Database Server: PostgreSQL 14.5
Database Provider: Npgsql
Operating system: Windows 10
.NET Framework: 6.0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions