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
This error appeared after installing linq2db v4.3.0.
I created an example to demonstrate the issue.
Here is the database schema:
and here is the console sample app:
And here is the stack trace:
This example works without issues using linq2db v4.2.0.
I also managed to find a solution to fix this by changing this line
to this
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