How to use LINQ provider from F #?

What is the correct way to use LINQ queries in F # when using a provider (e.g. LINQ to NHibernate) to work the same way as in C # (same AST)?

My particular problem is that translating the request to F # causes an error while C # is running. This may be because F # does not generate the same AST. Roslyn provides the Visual Studio AST visualizer extension for C #, but I don't know any AST viewer for F #.

Having the following working C # request:

.First(someEntity => someEntity.SomeNullableInt.HasValue);

when switching to F #:

.First(fun someEntity -> someEntity.SomeNullableInt.HasValue)

it fails with the following error:

System.NotSupportedException: Boolean Invoke(System.Nullable`1[System.Int32])
>    at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitMethodCallExpression(MethodCallExpression expression)
   at NHibernate.Linq.Visitors.QueryModelVisitor.VisitWhereClause(WhereClause whereClause, QueryModel queryModel, Int32 index)
   at Remotion.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection`1 bodyClauses, QueryModel queryModel)
   at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)
   at NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root)
   at NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory, Boolean filter)
   at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)
   at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)
   at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)
   at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)
   at NHibernate.Linq.DefaultQueryProvider.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery)
   at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
   at NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)
   ...
Stopped due to error

Use .First(fun someEntity -> someEntity.SomeReferenceType <> null)works correctly, although this leads to the above: AST is generated differently when used .HasValue.

+4
1

, F #, , #. , , F # , -

someEntity => ((System.Func<bool?,bool>)(copyOfNullable => copyOfNullable.HasValue)).Invoke(someEntity.SomeNullableInt)

, , , , F # , , , .

, - , , , -

.First(Simplify(fun someEntity -> someEntity.SomeNullableInt.HasValue))
+4

Source: https://habr.com/ru/post/1610406/


All Articles