Closed garkushin closed 7 months ago
Will prepare sample tomorrow, sorry for delay. It is strange that CTE won't work.
Here is an error while trying to execute "cte", thought it might help.
System.InvalidOperationException
HResult=0x80131509
Сообщение = variable 'node' of type 'Domain.Entities.Node' referenced from scope '', but it is not defined
Источник = System.Linq.Expressions
Трассировка стека:
в System.Linq.Expressions.Compiler.VariableBinder.Reference(ParameterExpression node, VariableStorageKind storage)
в System.Linq.Expressions.Compiler.VariableBinder.VisitParameter(ParameterExpression node)
в System.Linq.Expressions.ParameterExpression.Accept(ExpressionVisitor visitor)
в System.Linq.Expressions.Compiler.VariableBinder.Visit(Expression node)
в System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1 nodes)
в System.Linq.Expressions.Compiler.VariableBinder.VisitLambda[T](Expression`1 node)
в System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
в System.Linq.Expressions.Compiler.VariableBinder.Visit(Expression node)
в System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda)
в System.Linq.Expressions.LambdaExpression.Compile()
в LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.EvaluateExpression(Expression expr)
в System.Linq.Enumerable.SelectIListIterator`2.ToArray()
в LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.<>c__DisplayClass39_0.<TransformExpression>g__LocalTransform|0(Expression e)
в LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.<>c__DisplayClass39_0.<TransformExpression>b__1(Expression e)
в LinqToDB.Expressions.Extensions.<>c.<Transform>b__16_0(Func`2 f, Expression e)
в LinqToDB.Expressions.TransformInfoVisitor`1.Transform(Expression expr)
в LinqToDB.Expressions.TransformInfoVisitor`1.Transform[T](IList`1 source)
в LinqToDB.Expressions.TransformInfoVisitor`1.Transform(Expression expr)
в LinqToDB.Expressions.TransformInfoVisitor`1.Transform(Expression expr)
в LinqToDB.Expressions.TransformInfoVisitor`1.Transform(Expression expr)
в LinqToDB.Expressions.TransformInfoVisitor`1.Transform[T](IList`1 source)
в LinqToDB.Expressions.TransformInfoVisitor`1.Transform(Expression expr)
в LinqToDB.Expressions.TransformInfoVisitor`1.Transform[T](IList`1 source)
в LinqToDB.Expressions.TransformInfoVisitor`1.Transform(Expression expr)
в LinqToDB.Expressions.TransformInfoVisitor`1.Transform[T](IList`1 source)
в LinqToDB.Expressions.TransformInfoVisitor`1.Transform(Expression expr)
в LinqToDB.Expressions.Extensions.Transform(Expression expr, Func`2 func)
в LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.TransformExpression(Expression expression, IDataContext dc, DbContext ctx, IModel model)
в LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.TransformExpression(Expression expression, IDataContext dc, DbContext ctx, IModel model)
в LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsDataConnection.ProcessExpression(Expression expression)
в LinqToDB.Linq.Query`1.GetQuery(IDataContext dataContext, Expression& expr, Boolean& dependsOnParameters)
в LinqToDB.Linq.ExpressionQuery`1.GetQuery(Expression& expression, Boolean cache, Boolean& dependsOnParameters)
в LinqToDB.Linq.ExpressionQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
в LinqToDB.EntityFrameworkCore.Internal.LinqToDBForEFQueryProvider`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
в System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
в System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
в Application.Common.Interfaces.TemplateMigrationMethod.<Up>d__3.MoveNext() в src\Application\Common\MigrationMethods\TemplateMigrationMethod.cs:строка 40
Can you create small reproducible sample? I cannot reproduce. Looks like problem with EF Core extension itself, but I cannot figure out what happened.
It can be sample without database. I just need the same exception.
Also NewArray
and other custom extensions are needed.
Also with defining function (not tested):
[ExpressionMethod(nameof(SearchGraph3Impl))]
public static IQueryable<GraphPath> SearchGraph3(IDataContext dc, Guid root, string types, int depth, int limit)
{
return SearchGraph3Impl().Compile().Invoke(dc, root, types, depth, limit);
}
private static Expression<Func<IDataContext, Guid, string, int, int, IQueryable<GraphPath>>> SearchGraph3Impl()
{
return (dc, root, types, depth, limit) =>
dc.FromSql<GraphPath>($"search_graph({root}, array[{types}]::edge_type[], {depth}, {limit})");
}
https://github.com/garkushin/repro-191 I did not clean up the code "Minimally reproduce" state, there remains a lot of redundant code, but the error is reproduced. I hope you understand.
The option that you describe will try will write about the result later.
Well, finally I see what happened. Will figure out how to solve that elegantly. But actually problem in your code.
I look forward to hearing from you. I'm wondering where the error is :)
Sorry for delay. Problem is that CTE in the SQL cannot have parameters. If you call SearchGraph4
with node
parameter which can be evaluated, linq2db
can build SQL. But in query:
from node in db.Nodes
let grath = db.SearchGraph(node, types, 10, 10)
...
node
is dynamic parameter which depends on record from other recordset. In many other cases we can solve this limitation by ExpressionMethod
but not for this task. Since CTE cannot be parametrized we will fail.
It's a pity. I tried the version you described earlier and got the same error. https://github.com/linq2db/linq2db.EntityFrameworkCore/issues/191#issuecomment-964934430
"variable 'node' of type 'Domain.Entities.Node' referenced from scope '', but it is not defined"
Any more ideas how I can do this?
If nothing can be done, the issue can be closed, but I would like to receive a definitive answer.
After some time, I came back to this issue, here is the solution I was looking for:
[Sql.TableFunction(Name="search_graph")]
public IQueryable<GraphPath> SearchGraph([ExprParameter] Guid root, int depth, int limit)
{
using var ctx = this.CreateLinqToDBContext();
var method = MethodHelper.GetMethodInfo(SearchGraph, root, depth, limit);
return ctx.GetTable<GraphPath>(this, method, root, depth, limit);
}
Good afternoon, and I am using Microsoft.EntityFrameworkCore 5.0.11 and linq2db.EntityFrameworkCore 5.0.8, I am trying your library for the first time and I have a few questions. I have:
SQL function with signature
which returns a table with multiple rows of data.
I want to get: I need to implement requests like
How I tried to implement this:
i had several attempts to implement this
version 1, use FromSqlRaw EF Core
version 2, use FromSql linq2db
version 3, use Sql.Extension
version 4, use recursive CTE
Version 3 did not work even once, I found out that this is related to the return type IQueryable, if you use a primitive return type, then SQL is generated, but, of course, it does not work correctly.
Is there any way to use Sql.Extension with an IQueryable return type?
Versions 1,2,4 work as separate queries of the form
But they do not work inside other requests, as in the example above.
Tell me which way should I go to implement this? And one more thing, is it possible to combine EF Core DbContext and LinqToDbContext in one request as it is done in versions 2 and 4?