Giter Site home page Giter Site logo

6bee / remote.linq Goto Github PK

View Code? Open in Web Editor NEW
307.0 14.0 24.0 3.83 MB

Simply LINQ your remote resources...

License: MIT License

Batchfile 0.06% C# 99.94%
linq-expressions arbitrary-linq-queries expression-trees entity entity-framework remote streaming linq linq-provider

remote.linq's Introduction

Remote.Linq

Github Workflow

branch AppVeyor Travis CI Codecov.io Codacy CodeFactor License
main AppVeyor Build Status Travis Build Status codecov Codacy CodeFactor GitHub license
package nuget myget
Remote.Linq NuGet Badge MyGet Pre Release
Remote.Linq.Async.Queryable NuGet Badge MyGet Pre Release
Remote.Linq.EntityFramework NuGet Badge MyGet Pre Release
Remote.Linq.EntityFrameworkCore NuGet Badge MyGet Pre Release
Remote.Linq.Newtonsoft.Json NuGet Badge MyGet Pre Release
Remote.Linq.protobuf-net NuGet Badge MyGet Pre Release
Remote.Linq.Text.Json NuGet Badge MyGet Pre Release

Description

Remote.Linq is a small and easy to use - yet very powerful - library to translate LINQ expression trees to strongly typed, serializable expression trees and vice versa. It provides functionality to send arbitrary LINQ queries to a remote service to be applied and executed against any enumerable or queryable data collection.

Building a LINQ interface for custom services is made a breeze by using Remote.Linq.

Features

  • Translate LINQ expressions into serializable expression trees (remote LINQ expression) and vice versa.
  • Build remote single-type query services (paging, sorting, filtering).
  • Build remote complex LINQ query services (arbitrary LINQ query including joins, groupings, aggregations, projections, etc.).

Scope

In contrast to re-linq, this project enables serialization and deserialization of expression trees and applying LINQ expressions to other LINQ providers e.g. linq-to-object, linq-to-entity, etc.

Remote.Linq makes it super easy to implement a service allowing LINQ queries defined on a client to be executed on a remote server.

Write operations (insert/update/delete) have to be implemented by other means if needed. InfoCarrier.Core might be interesting for such scenarios.

How to Use

Check-out Remote.Linq.Samples.sln and samples folder for a number of sample use cases.

Client Code Sample

Implement a repository class to set-up server connection and expose the queryable data sets (IQueryable<>)

public class ClientDataRepository
{
    private readonly Func<Expression, DynamicObject> _dataProvider;

    public RemoteRepository(string uri)
    {
        _dataProvider = expression =>
            {
                // setup service connectivity
                using IQueryService service = CreateServerConnection(uri);
                // send expression to service and get back results
                DynamicObject result = service.ExecuteQuery(expression);
                return result;
            };
    }

    public IRemoteQueryable<Blog> Blogs => RemoteQueryable.Factory.CreateQueryable<Blog>(_dataProvider);
   
    public IRemoteQueryable<Post> Posts => RemoteQueryable.Factory.CreateQueryable<Post>(_dataProvider);
   
    public IRemoteQueryable<User> Users => RemoteQueryable.Factory.CreateQueryable<User>(_dataProvider);
    
    // where IRemoteQueryable<out T> is IQueryable<out T>
}

Use your repository to compose LINQ query and let the data be retrieved from the backend service

var repository = new ClientDataRepository("https://myserver/queryservice");

var myBlogPosts = (
    from blog in repository.Blogs
    from post in blog.Posts
    join owner in repository.Users on blog.OwnerId equals owner.Id
    where owner.login == "hi-its-me"
    select new 
    {
        post.Title,
        post.Date,
        Preview = post.Text.Substring(0, 50)
    }).ToList();

Server Code Sample

Implement the backend service to handle the client's query expression by applying it to a data source e.g. an ORM

public interface IQueryService : IDisposable
{
    DynamicObject ExecuteQuery(Expression queryExpression);
}

public class QueryService : IQueryService
{
    // any linq provider e.g. entity framework, nhibernate, ...
    private IDataProvider _datastore = new ObjectRelationalMapper();

    // you need to be able to retrieve an IQueryable by type
    private Func<Type, IQueryable> _queryableProvider = type => _datastore.GetQueryableByType(type);

    public DynamicObject ExecuteQuery(Expression queryExpression)
    {
        // `Execute` is an extension method provided by Remote.Linq
        // it applies an expression to a data source and returns the result
        return queryExpression.Execute(queryableProvider: _queryableProvider);
    }

    public void Dispose() => _datastore.Dispose();
}

Async Code Sample

IAsyncRemoteQueryable<TEntity> asyncQuery =
  RemoteQueryable.Factory.CreateAsyncQueryable<TEntity>(...);
TEntity[] result = await asyncQuery.ToArrayAsync().ConfigureAwait(false);

// where interface IAsyncRemoteQueryable<out T> is IRemoteQueryable<out T> is IQueryable<out T>

Async Stream Code Sample

IAsyncRemoteStreamQueryable<TEntity> asyncStreamQuery =
  RemoteQueryable.Factory.CreateAsyncStreamQueryable<TEntity>(...);
await foreach (TEntity item in asyncStreamQuery.ConfigureAwait(false))
{
}

// where interface IAsyncRemoteStreamQueryable<out T> is IQueryable<out T>

See MS tutorial on async streams for more info.

Remote.Linq.Async.Queryable

Provides interoperability with Interactive Extensions (Ix.NET / System.Linq.Async.Queryable).

How to Use

System.Linq.IAsyncQueryable<TEntity> asyncQuery =
  RemoteQueryable.Factory.CreateAsyncQueryable<TEntity>(...);
await foreach (TEntity item in asyncQuery.ConfigureAwait(false))
{
}

Remote.Linq.EntityFramework / Remote.Linq.EntityFrameworkCore

Remote linq extensions for Entity Framework and Entity Framework Core.

Use this package when using features specific to EF6 and EF Core:

  • Apply eager-loading (Include-expressions)

  • Make use of DB functions
    e.g. queryable.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Name, "%fruit%"))

How to Use

Client Code Sample

Query blogs including posts and owner

using var repository = new RemoteRepository();
var blogs = repository.Blogs
    .Include(x => x.Posts).ThenInclude(x => x.Owner)
    .ToList();

Server Code Sample

Execute query on database via EF Core

public DynamicObject ExecuteQuery(Expression queryExpression)
{
    using var dbContext = new DbContext();
    return queryExpression.ExecuteWithEntityFrameworkCore(dbContext);
}

Remote.Linq.Newtonsoft.Json

Provides Json.NET serialization settings for Remote.Linq types.

How to Use

// Serialization
TValue value = ...;
JsonSerializerSettings serializerSettings = new JsonSerializerSettings().ConfigureRemoteLinq(); 
string json = JsonConvert.SerializeObject(value, serializerSettings); 
TValue copy = JsonConvert.DeserializeObject<TValue>(json, serializerSettings); 

Remote.Linq.Text.Json

Provides System.Text.Json serialization settings for Remote.Linq types.

How to Use

// Serialization
TValue value = ...;
JsonSerializerOptions serializerOptions = new JsonSerializerOptions().ConfigureRemoteLinq();
string json = JsonSerializer.Serialize(value, serializerOptions);
TValue copy = JsonSerializer.Deserialize<TValue>(json, serializerOptions);
// Microsoft.AspNetCore.Hosting [WebHostBuilder]
new WebHostBuilder()
  .ConfigureServices(services => services
    .AddMvcCore()
    .AddJsonOptions(options => options.JsonSerializerOptions.ConfigureRemoteLinq()));
// Microsoft.AspNetCore.Hosting [WebApplicationBuilder]
var builder = WebApplication.CreateBuilder();
builder.Services
  .AddMvcCore()
  .AddJsonOptions(options => options.JsonSerializerOptions.ConfigureRemoteLinq());
// System.Net.Http.HttpClient
TValue value = ...;
Uri uri = ...;
var serializerOptions = new JsonSerializerOptions().ConfigureRemoteLinq();
using var httpClient = new HttpClient();
await httpClient.PostAsJsonAsync(uri, value, serializerOptions);

remote.linq's People

Contributors

6bee avatar dependabot[bot] avatar plan-collinalpert avatar rogerwaters avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

remote.linq's Issues

System.ArgumentException : Argument types do not match

There is an issue in deserializing serialized expressions with nested and multiple parameters as shown in the following code snippet. It gives the "Argument types don't match" error. We used "Remote.Linq 5.6.1" and "Newtonsoft.Json 11.0.2", and we tried both ".net46" and ".netcoreapp2.0" target frameworks.

    class Program
    {
        static void Main(string[] args)
        {
            Expression<Func<int, Dataset<int, string>>> expr = n => new Dataset<int, string>(new DataShard<int, string>(n), 5);
            var closureEliminator = new ClosureEliminator();
            Expression visitedExpr = closureEliminator.Visit(expr);

            var serializedExpr = SerializationHelper.Serialize(visitedExpr);
            var outputExpr = SerializationHelper.Deserialize(serializedExpr);
        }
    }

    public class Dataset<TKey, TPayload>
    {
        public Dataset() { }
        public Dataset(DataShard<TKey, TPayload> shard, int x) : this() { }
    }

    public class DataShard<TKey, TPayload>
    {
        public DataShard(){ }
        public DataShard(int n) : this(){ }
    }
       
    public class SerializationHelper
    {
        private SerializationHelper() { }

        private static readonly JsonSerializerSettings _serializerSettings
          = new JsonSerializerSettings
            {
                TypeNameHandling = TypeNameHandling.Auto,
                NullValueHandling = NullValueHandling.Ignore,
                TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Full,
            };

        internal static string Serialize(Expression expression)
        {
            var toSerialize = expression.ToRemoteLinqExpression()
                                        .ReplaceGenericQueryArgumentsByNonGenericArguments();
            return JsonConvert.SerializeObject(toSerialize, _serializerSettings);
        }

        internal static Expression Deserialize(string expression)
        {
            var deserialized = JsonConvert.DeserializeObject<Remote.Linq.Expressions.LambdaExpression>(
                                                                expression, _serializerSettings);
            var ret = deserialized.ReplaceNonGenericQueryArgumentsByGenericArguments().ToLinqExpression();
            return ret;
        }
    }

    public class ClosureEliminator : System.Linq.Expressions.ExpressionVisitor
    {
        protected override Expression VisitMember(MemberExpression node)
        {
            if ((node.Expression != null) && (node.Expression.NodeType == ExpressionType.Constant))
            {
                object target = ((ConstantExpression)node.Expression).Value, value;
                switch (node.Member.MemberType)
                {
                    case System.Reflection.MemberTypes.Property:
                        value = ((System.Reflection.PropertyInfo)node.Member).GetValue(target, null);
                        break;
                    case System.Reflection.MemberTypes.Field:
                        value = ((System.Reflection.FieldInfo)node.Member).GetValue(target);
                        break;
                    default:
                        value = target = null;
                        break;
                }
                if (target != null)
                {
                    if (value.GetType().IsSubclassOf(typeof(Expression)))
                    {
                        return this.Visit(value as Expression);
                    }
                    else
                    {
                        return Expression.Constant(value, node.Type);
                    }
                }
            }
            return base.VisitMember(node);
        }
    }

    public struct ObjectWrapper
    {
        public string type;
        public string data;
    }

Breaking changes in 6.0

I see that you throw InvalidProviderException on ExecuteAsync, previously it just runs query synchronously without exception. What the purpose of this decision? I have some places which use ToArrayAsync and for testing I just pass array.AsQueryable and now it fails. Could you introduce a new extensions method AsRemoteAsyncQueryable?

n-Tier Entity Framework (ntieref) still active?

Hi Christof,
We just stumbled across your ntieref library, and we're excited about using it. However, we noticed that no new builds have been posted in over 2 years (1.9), and the "Issues" tab has been closed down.
Is the ntieref still active? Also, are there any other middle-tier libraries like the ntieref that we should be considering using? We're being forced by our server team NOT to connect directly with our SQL Server from our externally facing ASP.NET MVC application,, so we need a middle-tier app server, but really love the convenience offered by your ntieref library.
Thanks in advance!

SelectMany from a constant sequence

Add the following test to Remote.Linq.Tests.RemoteQueryable.When_running_query class

[Fact]
public void Should_return_orders_joined_with_chars()
{
	char[] array = { 'h', 'e', 'l', 'l', 'o' };
	var joinLocalVariable = (
		from i in _orderItemQueriable
		from s in array
		select new { i, s }
		).ToList();

	var joinNewArrayInit = (
		from i in _orderItemQueriable
		from s in new[] { 'h', 'e', 'l', 'l', 'o' }
		select new { i, s }
		).ToList();

	var joinConst = (
		from i in _orderItemQueriable
		from s in "hello"
		select new { i, s }
		).ToList();
}

The first two queries work fine, but the last one fails with

Result Message:	Expression of type 'System.Func`2[Remote.Linq.Tests.RemoteQueryable.TestData.OrderItem,System.String]' cannot be used for parameter of type 'System.Linq.Expressions.Expression`1[System.Func`2[Remote.Linq.Tests.RemoteQueryable.TestData.OrderItem,System.Collections.Generic.IEnumerable`1[System.Char]]]' of method 'System.Linq.IQueryable`1[<>f__AnonymousType3`2[Remote.Linq.Tests.RemoteQueryable.TestData.OrderItem,System.Char]] SelectMany[OrderItem,Char,<>f__AnonymousType3`2](System.Linq.IQueryable`1[Remote.Linq.Tests.RemoteQueryable.TestData.OrderItem], System.Linq.Expressions.Expression`1[System.Func`2[Remote.Linq.Tests.RemoteQueryable.TestData.OrderItem,System.Collections.Generic.IEnumerable`1[System.Char]]], System.Linq.Expressions.Expression`1[System.Func`3[Remote.Linq.Tests.RemoteQueryable.TestData.OrderItem,System.Char,<>f__AnonymousType3`2[Remote.Linq.Tests.RemoteQueryable.TestData.OrderItem,System.Char]]])'

Result StackTrace:	
at System.Linq.Expressions.Expression.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arg, ParameterInfo pi)
   at System.Linq.Expressions.Expression.ValidateArgumentTypes(MethodBase method, ExpressionType nodeKind, ReadOnlyCollection`1& arguments)
   at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitMethodCall(MethodCallExpression methodCallExpression) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 868
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 618
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.ToExpression(Expression expression) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 583
   at Remote.Linq.ExpressionTranslator.ToLinqExpression(Expression expression, ITypeResolver typeResolver) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 79
   at Remote.Linq.Expressions.ExpressionExtensions.PrepareForExecution(Expression expression, Func`2 queryableProvider, ITypeResolver typeResolver) in D:\remotelinq\src\Remote.Linq\Expressions\ExpressionExtensions.cs:line 153
   at Remote.Linq.Expressions.ExpressionExtensions.Execute(Expression expression, Func`2 queryableProvider, ITypeResolver typeResolver, Func`2 resultPorjector, IDynamicObjectMapper mapper, Func`2 setTypeInformation) in D:\remotelinq\src\Remote.Linq\Expressions\ExpressionExtensions.cs:line 89
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.<>c__DisplayClass3_0.<.ctor>b__2(Expression x) in D:\remotelinq\test\Remote.Linq.Tests\RemoteQueryable\When_running_query.cs:line 22
   at Remote.Linq.DynamicQuery.RemoteQueryProvider`1.Execute[TResult](Expression expression) in D:\remotelinq\src\Remote.Linq\DynamicQuery\RemoteQueryProvider`.cs:line 43
   at Remote.Linq.DynamicQuery.RemoteQueryable`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() in D:\remotelinq\src\Remote.Linq\DynamicQuery\RemoteQueryable`.cs:line 22
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.Should_return_orders_joined_with_chars() in D:\remotelinq\test\Remote.Linq.Tests\RemoteQueryable\When_running_query.cs:line 100

This example may look a bit constructed, but unfortunately we are getting the same error in more practical situations when the LINQ expression is built dynamically, e.g. from the Remotion.Linq model. The expression builder (over which we have no control) is emitting a ConstantExpression(fixed_array) for the join, which causes ToLinqExpression to fail.

I did a bit of debugging and it seems like in the first two queries the arrays are wrapped as VariableQueryArgumentList whilst in the third case the constant is passed literally.

EF6, StackOverflowException [SOLVED]

When trying to get this working (possibly incorrectly), if the EF connection of the context for a CodeFirst setup is left in the default behavior (open, exec, close) an exception is thrown: The connection is not open. why, I do not know, it's expecting the connection to be opened for it, so I go ahead and do that, I manually open the connection and it results in a stack overflow:

using Aqua.Dynamic;
using log4net;
using Remote.Linq.Expressions;
using System.Collections.Generic;

namespace Project.Repo.Repo
{
    public class RemoteQueryRepo : BaseRepo, IRemoteQueryRepo
    {
        private readonly ILog _log4Net;
        public RemoteQueryRepo()
        {
            _log4Net = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        }
        public IEnumerable<DynamicObject> RemoteQuery(Expression expression)
        {
            Db.Database.Connection.Open();
            return expression.Execute(queryableProvider: (type) => Db.GetQueryableByType(type));
        }
    }
}

System.Core.dll!System.Linq.Enumerable.CombinePredicates.AnonymousMethod__0(System.__Canon x)	Unknown
 	System.Core.dll!System.Linq.Enumerable.WhereArrayIterator<System.Reflection.PropertyInfo>.MoveNext()	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.PopulateObjectMembers(System.Type type, object from, Aqua.Dynamic.DynamicObject to, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.ToContext.TryGetOrCreateNew(System.Type sourceType, object from, System.Func<System.Type, object, System.Func<System.Type, bool>, Aqua.Dynamic.DynamicObject> factory, System.Action<System.Type, object, Aqua.Dynamic.DynamicObject, System.Func<System.Type, bool>> initializer, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.MapInternal(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Remote.Linq.dll!Remote.Linq.DynamicQuery.DynamicQueryResultMapper.MapToDynamicObjectGraph(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.MapToDynamicObjectIfRequired(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.PopulateObjectMembers(System.Type type, object from, Aqua.Dynamic.DynamicObject to, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.ToContext.TryGetOrCreateNew(System.Type sourceType, object from, System.Func<System.Type, object, System.Func<System.Type, bool>, Aqua.Dynamic.DynamicObject> factory, System.Action<System.Type, object, Aqua.Dynamic.DynamicObject, System.Func<System.Type, bool>> initializer, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.MapInternal(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Remote.Linq.dll!Remote.Linq.DynamicQuery.DynamicQueryResultMapper.MapToDynamicObjectGraph(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.MapToDynamicObjectIfRequired(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.MapToDynamicObjectIfRequired.AnonymousMethod__0(object x)	Unknown
 	System.Core.dll!System.Linq.Enumerable.WhereSelectEnumerableIterator<object, object>.MoveNext()	Unknown
 	System.Core.dll!System.Linq.Buffer<object>.Buffer(System.Collections.Generic.IEnumerable<object> source)	Unknown
 	System.Core.dll!System.Linq.Enumerable.ToArray<object>(System.Collections.Generic.IEnumerable<object> source)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.MapToDynamicObjectIfRequired(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.PopulateObjectMembers(System.Type type, object from, Aqua.Dynamic.DynamicObject to, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.ToContext.TryGetOrCreateNew(System.Type sourceType, object from, System.Func<System.Type, object, System.Func<System.Type, bool>, Aqua.Dynamic.DynamicObject> factory, System.Action<System.Type, object, Aqua.Dynamic.DynamicObject, System.Func<System.Type, bool>> initializer, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.MapInternal(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Remote.Linq.dll!Remote.Linq.DynamicQuery.DynamicQueryResultMapper.MapToDynamicObjectGraph(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.MapToDynamicObjectIfRequired(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.PopulateObjectMembers(System.Type type, object from, Aqua.Dynamic.DynamicObject to, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.ToContext.TryGetOrCreateNew(System.Type sourceType, object from, System.Func<System.Type, object, System.Func<System.Type, bool>, Aqua.Dynamic.DynamicObject> factory, System.Action<System.Type, object, Aqua.Dynamic.DynamicObject, System.Func<System.Type, bool>> initializer, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.MapInternal(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Remote.Linq.dll!Remote.Linq.DynamicQuery.DynamicQueryResultMapper.MapToDynamicObjectGraph(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.MapToDynamicObjectIfRequired(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.MapToDynamicObjectIfRequired.AnonymousMethod__0(object x)	Unknown
 	System.Core.dll!System.Linq.Enumerable.WhereSelectEnumerableIterator<object, object>.MoveNext()	Unknown
 	System.Core.dll!System.Linq.Buffer<object>.Buffer(System.Collections.Generic.IEnumerable<object> source)	Unknown
 	System.Core.dll!System.Linq.Enumerable.ToArray<object>(System.Collections.Generic.IEnumerable<object> source)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.MapToDynamicObjectIfRequired(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.PopulateObjectMembers(System.Type type, object from, Aqua.Dynamic.DynamicObject to, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.ToContext.TryGetOrCreateNew(System.Type sourceType, object from, System.Func<System.Type, object, System.Func<System.Type, bool>, Aqua.Dynamic.DynamicObject> factory, System.Action<System.Type, object, Aqua.Dynamic.DynamicObject, System.Func<System.Type, bool>> initializer, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.MapInternal(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Remote.Linq.dll!Remote.Linq.DynamicQuery.DynamicQueryResultMapper.MapToDynamicObjectGraph(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.MapToDynamicObjectIfRequired(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.PopulateObjectMembers(System.Type type, object from, Aqua.Dynamic.DynamicObject to, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.ToContext.TryGetOrCreateNew(System.Type sourceType, object from, System.Func<System.Type, object, System.Func<System.Type, bool>, Aqua.Dynamic.DynamicObject> factory, System.Action<System.Type, object, Aqua.Dynamic.DynamicObject, System.Func<System.Type, bool>> initializer, System.Func<System.Type, bool> setTypeInformation)	Unknown
 	Aqua.dll!Aqua.Dynamic.DynamicObjectMapper.MapInternal(object obj, System.Func<System.Type, bool> setTypeInformation)	Unknown

Premature evaluation of static properties

We are experiencing a problem Remote.Linq-ing the new EF.Functions.Like() feature, and the reason is likely that RL is translating a static property access expression to a constant instead of leaving it "as is".

I made a little repro

public class DbFunctions
{
    internal DbFunctions()
    {
    }

    public bool Like(string matchExpression, string pattern) => true;
}

public static class EF
{
    public static DbFunctions Functions { get; } = new DbFunctions();
}

[Fact]
public void DbFunctionsTest()
{
    var result = _productQueryable.Where(p => EF.Functions.Like(p.Name, "%")).ToList();

    result.Count().ShouldBe(5);
}
System.Exception : Failed to pick matching constructor for type Remote.Linq.Tests.RemoteQueryable.When_running_query+DbFunctions
   at Aqua.Dynamic.DynamicObjectMapper.MapInternal(DynamicObject obj, Type type)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitConstant(ConstantExpression constantValueExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.<VisitNew>b__10_1(Expression a)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Dynamic.Utils.CollectionExtensions.ToReadOnly[T](IEnumerable`1 enumerable)
   at System.Linq.Expressions.Expression.New(ConstructorInfo constructor, IEnumerable`1 arguments)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitNew(NewExpression newExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitMember(MemberExpression memberExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitLambda(LambdaExpression lambdaExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitUnary(UnaryExpression unaryExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.<VisitMethodCall>b__27_0(Expression x)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.ToExpression(Expression expression)
   at Remote.Linq.ExpressionTranslator.ToLinqExpression(Expression expression, ITypeResolver typeResolver)
   at Remote.Linq.Expressions.ExpressionExtensions.PrepareForExecution(Expression expression, Func`2 queryableProvider, ITypeResolver typeResolver)
   at Remote.Linq.Expressions.ExpressionExtensions.Execute(Expression expression, Func`2 queryableProvider, ITypeResolver typeResolver, Func`2 resultPorjector, IDynamicObjectMapper mapper, Func`2 setTypeInformation)
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.<>c__DisplayClass11_1.<.ctor>b__0(Expression expression) in D:\Projects\InfoCarrierNG\remotelinq\test\Remote.Linq.Tests\RemoteQueryable\When_running_query.cs:line 66
   at Remote.Linq.DynamicQuery.RemoteQueryProvider`1.Execute[TResult](Expression expression)
   at Remote.Linq.DynamicQuery.RemoteQueryable`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.DbFunctionsTest() 

Deserialization of LambdaExpression fails when trying to recreate client side DisplayClass on the server side.

I have a Client Server setup where I am trying to use Remote.Linq to transfer expression from the client to the server process
and evaluate the expression on the server. I have a following simplified expression:

 public class Person {
     public short State { get; set; }
  }
   public class Client {
     public BusinessLogic() {
	short state = 95; 

	ServerCallWithFilter<Person>(p => p.State == state);
     }

    public ServerCallWithFilter<T>(Expression<Func<T, bool> predicate>) {

	Console.WriteLine($"Predicate: {predicate}"); 

	Remote.Linq.Expressions.LambdaExpression remoteLambda;
        remoteLambda = predicate.ToRemoteLinqExpression();
	
	Console.WriteLine($"RemoteLambda: {remoteLambda}");

	// Send the predicate to the server and receive results. 
    }
}

When the Lambda expression is printed out it looks like this:

p => (Convert(p.State) == Convert(value(ExpressionSerialization.Program+<>c__DisplayClass1_0).state))

And the remote linq lambda looks like the following:

p => (Convert(p.State) Equal Convert(Remote.Linq.DynamicQuery.ConstantQueryArgument.state))

When the Remote.Linq LambdaExpression is passed to the server side the deserialization fails because the server side is unable to recreate the "ExpressionSerialization.Program+<>c__DisplayClass1_0" type and throws an expression.

When I change the code so the state variable is int instead of a short then Remote.Linq can replace DisplayClass with the actual value and the deserialization works on the server side:

    public BusinessLogic() {
	int state= 95; 

	ServerCallWithFilter<Person>(p => p.State == state);
    }

Predicate: p => (Convert(p.State) == value(ExpressionSerialization.Program+<>c__DisplayClass1_0).state)
RemoteLambda: p => (Convert(p.State) Equal New Remote.Linq.DynamicQuery.VariableQueryArgument`1System.Int32.Value)

After debugging I noticed that whenever Remote.Linq receives an expression like Convert(value(DisplayClass).member) during evaluation it stops because of the Convert expression...

I was wondering what way this should be fixed? Is this an issue with Remote.Linq or with the Aqua library?

Remote access to larger blobs (byte arrays) rather slow

Hi!

I use a remote repository in my asp.net MVC web application to access a EF entities from another locally running backend service. The entities contain largerer blob values which are mapped to byte array members. This works like a charm, except that getting such a blob of - says - 3 MB can take a few seconds, which I think is rather long. Is this the performance I should expect? Any advice how I could identify the bottleneck or how to improve it?

Thanks!

StackOverflowException on ToRemoteLinqExpression

Hi, I have System.StackOverflowException when I call ToRemoteLinqExpression. Can you help me?

var func = new Func<A, bool>(wagons => wagons.Number > 0);
            Expression<Func<A, bool>> exp = x => func(x);
            var a = exp.ToRemoteLinqExpression();

public class A {
        public int Number { get; set; }
    }

SingleOrDefault does not work

Hello, I am trying to use SingleOrDefaultAsync method and it fails when nothing was found.

example code in unit tests

[Fact]
public void Should_query_single_or_default_with_predicate()
    {
        var result = _queryable.SingleOrDefault(x => x.Value.ToUpper().Contains("asdfasdfasdfW"));
        result.Key.ShouldBe("2");
    }

Is this secure ?

Hi,

If this project exposes dbcontext for operations on the client (it's not clear it dose so) is it secure as to what operations it allows to be performed from the deserialized linq ? Can it also do insert, update or delete ?

Thanks!

ToLinqExpression does not resolve 'VariableQueryArgument' correctly

Having the following code:

CaseInfo info = new CaseInfo();
CaseInfo info2 = new CaseInfo();
info2.ID = 1;
info.Where( ci => ci.ID == info2.ID )

The "where" method is an extension:

public static void Where<T>(this T source, Expression<Func<CaseInfo, bool>> criterias)
{
var remoteexpr = criterias.Body.ToRemoteLinqExpression();
var linqexpr = remoteexpr.ToLinqExpression();
}

Now I can see that the "Right" Operand Expression in 'linqexpr' is of type 'Remote.Linq.DynamicQuery.VariableQueryArgument`1'. Is this a design issue - and if so, how to access the Expression of the Operand?

Feature request for asynchronous data provider support.

I tried to use Remote.Linq client side in an asynchronous manner. I might be doing it wrong, if not then please add support for this:

public class RemoteRepository
    {
        private readonly Func<Expression, Task<IEnumerable<DynamicObject>>> _dataProvider;

        public RemoteRepository()
        {
            //Func<Task<IEnumerable<DynamicObject>>> myFun = async () => await myTask;

            _dataProvider = async (expression) =>
            {
                // setup service connectivity
                //IQueryService service = new QueryService();
                // send expression to service and get back results

                JsonSerializerSettings serializerSettings = new JsonSerializerSettings();//.ConfigureRemoteLinq();
                string json = JsonConvert.SerializeObject(expression, serializerSettings);

                IEnumerable<DynamicObject> result = await API.RemoteQuery(json);
                return result;
            };
        }
        public IQueryable<Filter> Filters => RemoteQueryable.Factory.CreateQueryable<Filter>(_dataProvider);
    }

Unable to cast object of type 'System.Threading.Tasks.Task`1[System.Collections.Generic.IEnumerable`1[Aqua.Dynamic.DynamicObject]]' to type 'System.Collections.Generic.IEnumerable`1[Project.Repo.Filter]'.


   at Remote.Linq.DynamicQuery.ObjectResultCaster.MapResult[TResult](Object source, Expression expression)
   at Remote.Linq.DynamicQuery.RemoteQueryProvider`1.Execute[TResult](Expression expression)
   at Remote.Linq.DynamicQuery.RemoteQueryable`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)```

Missing overload in AsyncRemoteQuerable

I am using Remote.Linqe with OData endpoint and it uses IQuerable instead of IQuerable<T> to build queries, but AsyncRemoteQueryable does not have an overload for IEnumerable.GetEnumerator so it uses the base one from RemoteQueryable. But this implementation tries to deserialize to the IEnumerable interface with an exception: 'Failed to pick matching constructor for type System.Collections.IEnumerable'.

JsonSerializer and XmlSerializer don't serialize DynamicObject.Type property

I extended When_using_dynamic_object_for_complex_object_tree class with one more test

public class When_using_dynamic_object_for_complex_object_tree
{
    // ...

    public When_using_dynamic_object_for_complex_object_tree()
    {
        var originalObject = new DynamicObject()
        {
            { "DoubleValue", DoubleValue },
            { 
                "Reference", new DynamicObject(typeof(string))
                {
                    { "StringValue", StringValue },
                }
            },
        };

        serializedObject = originalObject.Serialize();
    }

    [Fact]
    public void Clone_should_contain_type_information()
    {
        var nestedObject = serializedObject["Reference"] as DynamicObject;

        (nestedObject.Type?.Type).ShouldBe(typeof(string));
    }
    
    // ...
}

It passes with BinaryFormatter, DataContractSerializer and NetDataContractSerializer, but fails with JsonSerializer and XmlSerializer.

Remote.Linq expressions with enums cause NotImplementedException

I add a simple enum property to class Remote.Linq.Tests.RemoteQueryable.QueryTestData.Product

public class Product
{
    // ...

    public System.ConsoleColor Color { get; set; }
}

The following queries are failing

public abstract class When_running_query
{
    // ...

    [Fact]
    public void Should_return_all_product_using_color_filter()
    {
        // [FAIL] string parser for type System.ConsoleColor is not implemented
        ConsoleColor red = ConsoleColor.Red;
        _productQueryable.Where(p => p.Color != red).ToList();

        // [FAIL] string parser for type System.Nullable`1[System.ConsoleColor] is not implemented
        ConsoleColor? nullableRed = ConsoleColor.Red;
        _productQueryable.Where(p => p.Color != nullableRed).ToList();
    }
}
Result StackTrace:	
   at Aqua.Dynamic.DynamicObjectMapper.ParseToNativeType(Type targetType, String value)
   at Aqua.Dynamic.DynamicObjectMapper.TryExplicitConversions(Type targetType, Object& value)
   at Aqua.Dynamic.DynamicObjectMapper.<CreatePropertyInitializer>b__35_0(Type type, DynamicObject item, Object obj)
   at Aqua.Dynamic.DynamicObjectMapper.ObjectFormatterContext`2.TryGetOrCreateNew(Type objectType, TFrom from, Func`3 factory, Action`3 initializer)
   at Aqua.Dynamic.DynamicObjectMapper.MapInternal(DynamicObject obj, Type type)
   at Aqua.Dynamic.DynamicObjectMapper.MapFromDynamicObjectIfRequired(Object obj, Type targetType)
   at Aqua.Dynamic.DynamicObjectMapper.MapFromDynamicObjectGraph(Object obj, Type targetType)
   at Aqua.Dynamic.DynamicObjectMapper.Map(DynamicObject obj, Type type)
   at Aqua.Dynamic.DynamicObjectMapper.Map(DynamicObject obj)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitConstant(ConstantExpression constantValueExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitMember(MemberExpression memberExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitUnary(UnaryExpression unaryExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitBinary(BinaryExpression binaryExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitLambda(LambdaExpression lambdaExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitUnary(UnaryExpression unaryExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.<VisitMethodCall>b__20_0(Expression x)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.ToExpression(Expression expression)
   at Remote.Linq.ExpressionTranslator.ToLinqExpression(Expression expression, ITypeResolver typeResolver)
   at Remote.Linq.Expressions.ExpressionExtensions.PrepareForExecution(Expression expression, Func`2 queryableProvider, ITypeResolver typeResolver)
   at Remote.Linq.Expressions.ExpressionExtensions.Execute(Expression expression, Func`2 queryableProvider, ITypeResolver typeResolver, Func`2 resultPorjector, IDynamicObjectMapper mapper, Func`2 setTypeInformation)
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.<>c__DisplayClass10_1.<.ctor>b__0(Expression expression)
   at Remote.Linq.DynamicQuery.RemoteQueryProvider`1.Execute[TResult](Expression expression)
   at Remote.Linq.DynamicQuery.RemoteQueryable`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.Should_return_all_product_using_color_filter()

ExpressionType.TypeIs is poorly supported

Add another test to Remote.Linq.Tests.RemoteQueryable.When_running_query

[Fact]
public void Should_return_all_product2()
{
    var result = _productQueriable.Where(p => p is TestData.Product).ToList();

    result.Count().ShouldBe(5);
}
Test Name:	Remote.Linq.Tests.RemoteQueryable.When_running_query.Should_return_all_product2
Test FullName:	Remote.Linq.Tests.RemoteQueryable.When_running_query.Should_return_all_product2
Test Source:	D:\remotelinq\test\Remote.Linq.Tests\RemoteQueryable\When_running_query.cs : line 35
Test Outcome:	Failed
Test Duration:	0:00:00,106

Result StackTrace:	
at System.Linq.Expressions.Expression.Lambda(Expression body, String name, Boolean tailCall, IEnumerable`1 parameters)
   at System.Linq.Expressions.Expression.Lambda(Expression body, ParameterExpression[] parameters)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitLambda(LambdaExpression lambdaExpression) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 977
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 621
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitUnary(UnaryExpression unaryExpression) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 774
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 615
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.<VisitMethodCall>b__20_0(Expression x) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 808
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitMethodCall(MethodCallExpression methodCallExpression) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 807
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 618
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.ToExpression(Expression expression) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 583
   at Remote.Linq.ExpressionTranslator.ToLinqExpression(Expression expression, ITypeResolver typeResolver) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 79
   at Remote.Linq.Expressions.ExpressionExtensions.PrepareForExecution(Expression expression, Func`2 queryableProvider, ITypeResolver typeResolver) in D:\remotelinq\src\Remote.Linq\Expressions\ExpressionExtensions.cs:line 153
   at Remote.Linq.Expressions.ExpressionExtensions.Execute(Expression expression, Func`2 queryableProvider, ITypeResolver typeResolver, Func`2 resultPorjector, IDynamicObjectMapper mapper, Func`2 setTypeInformation) in D:\remotelinq\src\Remote.Linq\Expressions\ExpressionExtensions.cs:line 89
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.<>c__DisplayClass3_0.<.ctor>b__1(Expression x) in D:\remotelinq\test\Remote.Linq.Tests\RemoteQueryable\When_running_query.cs:line 21
   at Remote.Linq.DynamicQuery.RemoteQueryProvider`1.Execute[TResult](Expression expression) in D:\remotelinq\src\Remote.Linq\DynamicQuery\RemoteQueryProvider`.cs:line 43
   at Remote.Linq.DynamicQuery.RemoteQueryable`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() in D:\remotelinq\src\Remote.Linq\DynamicQuery\RemoteQueryable`.cs:line 22
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.Should_return_all_product2() in D:\remotelinq\test\Remote.Linq.Tests\RemoteQueryable\When_running_query.cs:line 36
Result Message:	
Value cannot be null.
Parameter name: body

ParameterExpression lookup by name

Apparently it isn't quite impossible to have an expression with essentially different parameters sharing the same name in overlapping scopes. An interesting example can be found in EntityFrameworkCore's Where_subquery_expression_same_parametername test.

AssertQuery<Order, Order>((o1, o2) =>
    {
        var firstOrder = o1.First();
        Expression<Func<Order, bool>> expr = x => x.OrderID == firstOrder.OrderID;
        return o1.Where(x => o2.Where(expr).Where(o => o.CustomerID == x.CustomerID).Any());
    });

As you correctly mentioned parameters within an expression tree must be represented by the same parameter expression instance, so the uniqueness of names isn't really necessary for LINQ.

However during LINQ => RLinq => LINQ translation you match parameters by their names which in particular messes up the a.m. query and restores a formally inequivalent LINQ from RLinq.

Is it possible translate LINQ => RLinq in such a way that distinct instances of Linq.ParameterExpression are mapped to corresponding distinct instance of RLinq.ParameterExpression no matter how many times a specific parameter occurs in an expression tree? Then we probably could employ the in-built capabilities of serialization frameworks (IsReference=true) which will automatically ensure identity of RLinq.ParameterExpression instances on the recipient end. Finally RLinq => LINQ translation should also preserve the uniqueness without having to rely on parameter names.

Having little experience with serialization frameworks I may assume that not all of them natively support IsReference=true. Then RLinq.ParameterExpression could just carry some InternalIdentifier field for proper matching.

GroupBy with SelectMany causes System.ArgumentException

Standard sample application samples\RemoteQueryable\0_Standard\Client\Demo.cs

Console.WriteLine("\nGET ALL PRODUCTS:");
foreach (var i in repo.Products)
{
	Console.WriteLine("  {0} | {1} | {2:C}", i.Id, i.Name, i.Price);
}

I change the query to repo.Products.GroupBy(p => p.Id).SelectMany(g => g) and (obviously) expect the identical results.

Unfortunately the program crashes

System.ArgumentException
Expression of type 'System.Linq.IGrouping`2[System.Int32,Common.Model.Product]' cannot be used for return type 'System.Collections.Generic.IEnumerable`1[System.Int32]'
   at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expression& body, ReadOnlyCollection`1 parameters)
   at System.Linq.Expressions.Expression.Lambda(Type delegateType, Expression body, String name, Boolean tailCall, IEnumerable`1 parameters)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.ToLinqExpression(Expression expression, ITypeResolver typeResolver)

Unwanted reduction of ConstantExpression of type Nullable<bool>

Under certain conditions LinqExpressionToRemoteExpressionTranslator reduces binary expressions to unary ones

Although it is a clever thing to do, it doesn't feel like it's an essential responsibility of Remote.Linq, since one would rather appreciate Remote.Linq's ability to deliver the original query (as close as possible) from one peer to another. Do you remember why was it necessary to implement it that way?

Second, the logic doesn't check the actual type of ConstantExpressions. In particular it performs the reduction of expressions like SomeNullableBoolean == (bool?)true to unary SomeNullableBoolean which is incorrect. Here I admit it's probably only possible to run into such problem when queries are built dynamically (e.g. from Remotion.Linq model). You can try the following test in When_running_query class

[Fact]
public void Should_handle_const_nullable_bool()
{
    // [PASS]
    // .Where(p => Convert(p.Name.EndsWith("x"), bool?) == Convert(True, bool?))
    _productQueriable.Where(p => (bool?)p.Name.EndsWith("x") == (bool?)true).ToList();

    // [FAIL]
    // .Where(p => Convert(p.Name.EndsWith("x"), bool?) == Constant(True, bool?))
    System.Linq.Expressions.Expression<Func<TestData.Product, bool?>> expr
        = p => (bool?)p.Name.EndsWith("x");
    var lambda = (System.Linq.Expressions.LambdaExpression)expr;
    var predicate
        = System.Linq.Expressions.Expression.Lambda<Func<TestData.Product, bool>>(
            System.Linq.Expressions.Expression.Equal(
                lambda.Body,
                System.Linq.Expressions.Expression.Constant(true, typeof(bool?))),
            lambda.Parameters);
    _productQueriable.Where(predicate).ToList();
}
Result Message:	Expression of type 'System.Linq.Expressions.Expression`1[System.Func`2[Remote.Linq.Tests.RemoteQueryable.TestData.Product,System.Nullable`1[System.Boolean]]]' cannot be used for parameter of type 'System.Linq.Expressions.Expression`1[System.Func`2[Remote.Linq.Tests.RemoteQueryable.TestData.Product,System.Boolean]]' of method 'System.Linq.IQueryable`1[Remote.Linq.Tests.RemoteQueryable.TestData.Product] Where[Product](System.Linq.IQueryable`1[Remote.Linq.Tests.RemoteQueryable.TestData.Product], System.Linq.Expressions.Expression`1[System.Func`2[Remote.Linq.Tests.RemoteQueryable.TestData.Product,System.Boolean]])'

Result StackTrace:	
at System.Linq.Expressions.Expression.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arg, ParameterInfo pi)
   at System.Linq.Expressions.Expression.ValidateArgumentTypes(MethodBase method, ExpressionType nodeKind, ReadOnlyCollection`1& arguments)
   at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitMethodCall(MethodCallExpression methodCallExpression) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 868
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 618
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.ToExpression(Expression expression) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 583
   at Remote.Linq.ExpressionTranslator.ToLinqExpression(Expression expression, ITypeResolver typeResolver) in D:\remotelinq\src\Remote.Linq\ExpressionVisitors\ExpressionTranslator.cs:line 79
   at Remote.Linq.Expressions.ExpressionExtensions.PrepareForExecution(Expression expression, Func`2 queryableProvider, ITypeResolver typeResolver) in D:\remotelinq\src\Remote.Linq\Expressions\ExpressionExtensions.cs:line 153
   at Remote.Linq.Expressions.ExpressionExtensions.Execute(Expression expression, Func`2 queryableProvider, ITypeResolver typeResolver, Func`2 resultPorjector, IDynamicObjectMapper mapper, Func`2 setTypeInformation) in D:\remotelinq\src\Remote.Linq\Expressions\ExpressionExtensions.cs:line 89
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.<>c__DisplayClass3_0.<.ctor>b__1(Expression x) in D:\remotelinq\test\Remote.Linq.Tests\RemoteQueryable\When_running_query.cs:line 22
   at Remote.Linq.DynamicQuery.RemoteQueryProvider`1.Execute[TResult](Expression expression) in D:\remotelinq\src\Remote.Linq\DynamicQuery\RemoteQueryProvider`.cs:line 43
   at Remote.Linq.DynamicQuery.RemoteQueryable`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() in D:\remotelinq\src\Remote.Linq\DynamicQuery\RemoteQueryable`.cs:line 22
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.Should_handle_const_nullable_bool() in D:\remotelinq\test\Remote.Linq.Tests\RemoteQueryable\When_running_query.cs:line 42

I would suggest either to remove this logic completely (if possible) or at least check the type ConstantExpressions for bool.

ArgumentException : Argument types do not match

Test Should_query_product_categories_filterd_using_inline_enum fails if I replace == with .Equals

[Fact]
public void Should_query_product_categories_filterd_using_EQUALS_inline_enum()
{
    var query =
        from c in _categoryQueryable
        where c.CategoryType.Equals(CategoryType.NonFood)
        select c;
    var result = query.ToArray();
    result.Count().ShouldBe(1);
}
System.ArgumentException : Argument types do not match

StackTrace:	
   at System.Linq.Expressions.Expression.Constant(Object value, Type type)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitConstant(ConstantExpression constantValueExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitUnary(UnaryExpression unaryExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.<VisitMethodCall>b__20_0(Expression x)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitLambda(LambdaExpression lambdaExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitUnary(UnaryExpression unaryExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.<VisitMethodCall>b__20_0(Expression x)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.ToExpression(Expression expression)
   at Remote.Linq.ExpressionTranslator.ToLinqExpression(Expression expression, ITypeResolver typeResolver)
   at Remote.Linq.Expressions.ExpressionExtensions.PrepareForExecution(Expression expression, Func`2 queryableProvider, ITypeResolver typeResolver)
   at Remote.Linq.Expressions.ExpressionExtensions.Execute(Expression expression, Func`2 queryableProvider, ITypeResolver typeResolver, Func`2 resultPorjector, IDynamicObjectMapper mapper, Func`2 setTypeInformation)
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.<>c__DisplayClass9_1.<.ctor>b__0(Expression expression)
   at Remote.Linq.DynamicQuery.RemoteQueryProvider`1.Execute[TResult](Expression expression)
   at Remote.Linq.DynamicQuery.RemoteQueryable`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.Should_query_product_categories_filterd_using_inline_enum()

In our scenarios we observed the same error with .HasFlag instead of .Equals for bit-field enums, but I believe the nature of the bug should be the same?

Remote.Linq 5.8.2 with aqua-core 4.5.2 gives "System.ArgumentException"

The two latest official releases of Remote.Linq and aqua-core don't always play well together. The simplest way to reproduce the problem is to check out Remote.Linq v5.8.2 and replace the following lines in test/Remote.Linq.Tests/Remote.Linq.Tests.csproj

  <ItemGroup>
    <ProjectReference Include="..\..\src\Remote.Linq\Remote.Linq.csproj" />
    <ProjectReference Include="..\..\src\Remote.Linq.Newtonsoft.Json\Remote.Linq.Newtonsoft.Json.csproj" />
  </ItemGroup>

with

  <ItemGroup>
    <PackageReference Include="aqua-core" Version="4.5.2" />
    <PackageReference Include="Remote.Linq.Newtonsoft.Json" Version="5.8.2" />
  </ItemGroup>

The two tests will fail

Test Name:	Remote.Linq.Tests.RemoteQueryable.When_running_query+With_json_serializer.Should_query_anonymous_type_with_primitive_value_array_injected_as_variable_closure
Test FullName:	Remote.Linq.Tests.RemoteQueryable.When_running_query+With_json_serializer.Should_query_anonymous_type_with_primitive_value_array_injected_as_variable_closure
Test Source:	test\Remote.Linq.Tests\RemoteQueryable\When_running_query.cs : line 865
Test Outcome:	Failed
Test Duration:	0:00:00,611

Result1 Name:	Remote.Linq.Tests.RemoteQueryable.When_running_query+With_json_serializer.Should_query_anonymous_type_with_primitive_value_array_injected_as_variable_closure(type: typeof(byte[]), value: [0, 0])
Result1 Outcome:	Failed
Result1 Duration:	0:00:00,003
Result1 StackTrace:	
at System.Linq.Expressions.Expression.Constant(Object value, Type type)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitConstant(ConstantExpression constantValueExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.<VisitNew>b__10_1(Expression a)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Dynamic.Utils.CollectionExtensions.ToReadOnly[T](IEnumerable`1 enumerable)
   at System.Linq.Expressions.Expression.New(ConstructorInfo constructor, IEnumerable`1 arguments)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitNew(NewExpression newExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitMember(MemberExpression memberExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.<VisitNew>b__10_1(Expression a)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Dynamic.Utils.CollectionExtensions.ToReadOnly[T](IEnumerable`1 enumerable)
   at System.Linq.Expressions.Expression.New(ConstructorInfo constructor, IEnumerable`1 arguments, IEnumerable`1 members)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitNew(NewExpression newExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitLambda(LambdaExpression lambdaExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitUnary(UnaryExpression unaryExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.<VisitMethodCall>b__27_0(Expression x)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.Expressions.ExpressionExecutor.Transform(Expression expression)
   at Remote.Linq.Expressions.ExpressionExecutor.Execute(Expression expression)
   at Remote.Linq.Expressions.ExpressionExtensions.Execute(Expression expression, Func`2 queryableProvider, ITypeResolver typeResolver, IDynamicObjectMapper mapper, Func`2 setTypeInformation, Func`2 canBeEvaluatedLocally)
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.<>c__DisplayClass11_1.<.ctor>b__0(Expression expression) in test\Remote.Linq.Tests\RemoteQueryable\When_running_query.cs:line 80
   at Remote.Linq.DynamicQuery.RemoteQueryProvider`1.Execute[TResult](Expression expression)
   at Remote.Linq.DynamicQuery.RemoteQueryable`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
   at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source)
   at Shouldly.ShouldBeEnumerableTestExtensions.ShouldAllBe[T](IEnumerable`1 actual, Expression`1 elementPredicate, Func`1 customMessage)
   at Shouldly.ShouldBeEnumerableTestExtensions.ShouldAllBe[T](IEnumerable`1 actual, Expression`1 elementPredicate, String customMessage)
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.TestMethodFor_Should_query_anonymous_type_with_primitive_value_array_injected_as_variable_closure[T](T[] array) in test\Remote.Linq.Tests\RemoteQueryable\When_running_query.cs:line 875
Result1 Message:	System.ArgumentException : Argument types do not match
Result1 StandardOutput:
Result1 StandardError:

Result2 Name:	Remote.Linq.Tests.RemoteQueryable.When_running_query+With_json_serializer.Should_query_anonymous_type_with_primitive_value_array_injected_as_variable_closure(type: typeof(byte[]), value: [255, 255])
Result2 Outcome:	Failed
Result2 Duration:	0:00:00,003
Result2 StackTrace:	
at System.Linq.Expressions.Expression.Constant(Object value, Type type)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitConstant(ConstantExpression constantValueExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.<VisitNew>b__10_1(Expression a)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Dynamic.Utils.CollectionExtensions.ToReadOnly[T](IEnumerable`1 enumerable)
   at System.Linq.Expressions.Expression.New(ConstructorInfo constructor, IEnumerable`1 arguments)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitNew(NewExpression newExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitMember(MemberExpression memberExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.<VisitNew>b__10_1(Expression a)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Dynamic.Utils.CollectionExtensions.ToReadOnly[T](IEnumerable`1 enumerable)
   at System.Linq.Expressions.Expression.New(ConstructorInfo constructor, IEnumerable`1 arguments, IEnumerable`1 members)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitNew(NewExpression newExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitLambda(LambdaExpression lambdaExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitUnary(UnaryExpression unaryExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.<VisitMethodCall>b__27_0(Expression x)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Remote.Linq.ExpressionTranslator.RemoteExpressionToLinqExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.Expressions.ExpressionExecutor.Transform(Expression expression)
   at Remote.Linq.Expressions.ExpressionExecutor.Execute(Expression expression)
   at Remote.Linq.Expressions.ExpressionExtensions.Execute(Expression expression, Func`2 queryableProvider, ITypeResolver typeResolver, IDynamicObjectMapper mapper, Func`2 setTypeInformation, Func`2 canBeEvaluatedLocally)
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.<>c__DisplayClass11_1.<.ctor>b__0(Expression expression) in test\Remote.Linq.Tests\RemoteQueryable\When_running_query.cs:line 80
   at Remote.Linq.DynamicQuery.RemoteQueryProvider`1.Execute[TResult](Expression expression)
   at Remote.Linq.DynamicQuery.RemoteQueryable`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
   at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source)
   at Shouldly.ShouldBeEnumerableTestExtensions.ShouldAllBe[T](IEnumerable`1 actual, Expression`1 elementPredicate, Func`1 customMessage)
   at Shouldly.ShouldBeEnumerableTestExtensions.ShouldAllBe[T](IEnumerable`1 actual, Expression`1 elementPredicate, String customMessage)
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.TestMethodFor_Should_query_anonymous_type_with_primitive_value_array_injected_as_variable_closure[T](T[] array) in test\Remote.Linq.Tests\RemoteQueryable\When_running_query.cs:line 875
Result2 Message:	System.ArgumentException : Argument types do not match
Result2 StandardOutput:
Result2 StandardError:

DataContract serialization fails for const arrays

We run into another issue with dynamically built LINQ queries which contain ConstantExpressions of type array. This time the query crashes during serialization. Similar to #4 it works fine when the array is represented by a NewArrayInitExpression but fails when a (seemingly equivalent) ConstantExpression is being used.

Please run the following test in the Remote.Linq.Tests.RemoteQueryable.When_running_query class to reproduce the problem

[Fact]
public void ArrayContainsSerializationTest()
{
    System.Linq.Expressions.Expression<Func<Category, bool>> lambdaNewArrayInit =
        c => new[] { "Vehicles" }.Contains(c.Name);
    
    var mc = (System.Linq.Expressions.MethodCallExpression)lambdaNewArrayInit.Body;

    var lambdaConst = System.Linq.Expressions.Expression.Lambda<Func<Category, bool>>(
        System.Linq.Expressions.Expression.Call(
            mc.Method,
            System.Linq.Expressions.Expression.Constant(new[] { "Vehicles" }),
            mc.Arguments[1]),
        lambdaNewArrayInit.Parameters);

    _categoryQueriable.Where(lambdaNewArrayInit).ToList(); // [PASS]
    _categoryQueriable.Where(lambdaConst).ToList(); // [FAIL]
}

System.Runtime.Serialization.SerializationException : Type 'System.String[]' with data contract name 'ArrayOfstring:http://schemas.microsoft.com/2003/10/Serialization/Arrays' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.

And again it seems to have something to do with NOT using VariableQueryArgumentList in the second query.

Trivial anonymous projections lead to InvalidDataContractException

DataContractSerializer fails on both queries

_categoryQueryable.Select(c => new { i = 123 }).ToList();

int x = 123;
_categoryQueryable.Select(c => new { i = x }).ToList();

System.Runtime.Serialization.InvalidDataContractException : Type '<>f__AnonymousType5`1[System.Int32]' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.

Store/load Remote.Linq queries

Would be possible to store (and load) Remote.Linq queries to (for instance) a readable text format to (from) a file ?

How to map results to a different object?

I need to work with similar but differently named objects on client and server side.
It seems that ITypeResolver is there to solve this issue.
So I pass my implementation of ITypeResolver:

var employees = Remote.Linq.RemoteQueryable.Factory.CreateQueryable<Employee>(..., typeResolver: resultMapper: new EmployeeResolver());

However, EmployeeResolver.ResolveType is never hit.

Documentation question and download incomplete...

Hi there,
I'm a previous user of your N-Tier library, and I really appreciated the User's Manual that you had included in the doc folder. Is there any user/developer documentation available for the Remote.Linq?
Also, this may be me not being totally familiar with how to download stuff from GitHub, but the only way to download that I know of is by clicking on the "Clone or Download" button while viewing the root of the repository. Unfortunately, when I download and unzip that file, it doesn't include the test folder where the samples are. Once I drill down into the folders, downloading is only available one file at a time.
Thank you in advance for your response.

Deserialization needs fixing for Json.NET

Json deserialization fails using Remote.Linq.Newtonsoft.Json 5.4.0-alpha-015:

"The method or operation is not implemented." 
at Remote.Linq.JsonConverters.ConstantExpressionJsonConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)

Unnecessary roundtrips during query execution

The following query requires two roundtrips to execute

_productQueryable.Where(p => _categoryQueryable.Any() && p.Id >= 1)

It would first evaluate _categoryQueryable.Any() and then _productQueryable.Where(p => true && p.Id >= 1).

asyncExecuteWithEntityFramework

Hi,
I have not been able to find a way to execute a EF6 query async on the server.
I am currently using the following in my webapi query method.
var results = query.Expression.ExecuteWithEntityFramework(Context);
I sort of expected to find ExecuteWithEntityFrameworkAsync method.
Is this something the you never got to? Maybe you did not feel it is nessesary?

Expressions containing DateTimeOffset can not be serialized with DataContractSerializer

var dt = new DateTimeOffset();
System.Linq.Expressions.Expression<Func<bool, DateTimeOffset>> expression = x => dt;
var remoteExpression = expression.ToRemoteLinqExpression();
var serializedRemoteExpression = DataContractSerializationHelper.Serialize(remoteExpression);

fails with SerializationException

Type 'System.Runtime.Serialization.DateTimeOffsetAdapter' with data contract name 'DateTimeOffset:http://schemas.datacontract.org/2004/07/System' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.

Support Expression.Invoke

There exist scenarios like dotnet/efcore#5445 where filter conditions are built dynamically using Expression.Lambda/Expression.Invoke. Apparently those aren't yet fully supported by Remote.Linq-5.5.0-beta-002.

System.Linq.Expressions.Expression<Func<Category, bool>> expression = c => c.Name == "hello";
var parameter = System.Linq.Expressions.Expression.Parameter(typeof(Category), "c");

_categoryQueryable.Where(
    System.Linq.Expressions.Expression.Lambda<Func<Category, bool>>(
        System.Linq.Expressions.Expression.Invoke(expression, parameter), parameter)).ToList();

fails with

System.ArgumentException
Expression of type 'Remote.Linq.Expressions.LambdaExpression' cannot be invoked
   at System.Linq.Expressions.Expression.GetInvokeMethod(Expression expression)
   at System.Linq.Expressions.Expression.Invoke(Expression expression, IEnumerable`1 arguments)
   at Remote.Linq.ExpressionVisitors.ExpressionVisitorBase.VisitInvocation(InvocationExpression node)
   at Remote.Linq.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.LinqExpressionToRemoteExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.LinqExpressionToRemoteExpressionTranslator.VisitLambda(LambdaExpression node)
   at Remote.Linq.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.LinqExpressionToRemoteExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.LinqExpressionToRemoteExpressionTranslator.VisitUnary(UnaryExpression node)
   at Remote.Linq.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.LinqExpressionToRemoteExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.LinqExpressionToRemoteExpressionTranslator.<VisitMethodCall>b__24_0(Expression argument)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Remote.Linq.Expressions.MethodCallExpression..ctor(Expression insatnce, MethodInfo methodInfo, IEnumerable`1 arguments)
   at Remote.Linq.Expressions.MethodCallExpression..ctor(Expression insatnce, MethodInfo methodInfo, IEnumerable`1 arguments)
   at Remote.Linq.ExpressionTranslator.LinqExpressionToRemoteExpressionTranslator.VisitMethodCall(MethodCallExpression node)
   at Remote.Linq.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.LinqExpressionToRemoteExpressionTranslator.Visit(Expression expression)
   at Remote.Linq.ExpressionTranslator.LinqExpressionToRemoteExpressionTranslator.ToRemoteExpression(Expression expression)
   at Remote.Linq.ExpressionTranslator.ToRemoteLinqExpression(Expression expression)
   at Remote.Linq.DynamicQuery.RemoteQueryProvider`1.TranslateExpression(Expression expression, ITypeResolver typeResolver)
   at Remote.Linq.DynamicQuery.RemoteQueryProvider`1.Execute[TResult](Expression expression)
   at Remote.Linq.DynamicQuery.RemoteQueryable`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)

Issue using EF6 with variable query argument

I've got a Remote Linq expression I'm trying to execute against EF like below.

Client:

string myTestValue = "MyTestValue"
var remoteQueryable = RemoteQueryable.Create<MyEntity>((exp) => QueryService(exp))
                    .Where(d => d.TestProperty == myTestValue);

Server:
remoteLinqExpression.Execute(t => cp.MyEntities).ToList();
which fails with 'Only parameterless constructors and initializers are supported in LINQ to Entities.'

I believe the issue is with this part of the expression tree:

System.Linq.Queryable.Where(Remote.Linq.DynamicQuery.QueryableResourceDescriptor, Quote(d => (d.SMDsym Equal New Remote.Linq.DynamicQuery.VariableQueryArgument`1{System.String}('MyTestValue').Value)))`

because if I specify a string literal, rather than the variable then it works fine.

Note this did work when using LINQ To SQL, but started failing when I moved to EF6.

Error StackOverflowException

Hello,
I use
var repo = new RemoteRepository("localhost", 8899);
var partner = await repo.Partner.ToListAsync();
dataGridView1.DataSource = partner;
In version 5.8.2, everything works fine.
In versions 6.0.0, 6.1.1 and 6.2.0 I get this error:
Process is terminated due to StackOverflowException in Remote.Linq.dll.

In these versions this example doesn't work: 10_UsingJsonSerializationOverTcpAsync.

Thank you.

Support Universal Windows Platform

Since UWP10 support was withdrawn from netstandard1.6 we should aim to add support for UWP explicitely: target platform uap10.0

see .NET Standard Versions table

Announcement: Newtonsoft.Json (Json.NET) Configuration for Remote.Linq

Dependency on Newtonsoft.Json moved from Remote.Linq to package Remote.Linq.Newtonsoft.Json as of version 5.4.0-alpha-017.

To enable JSON serialization for Remote.Linq using Newtonsoft.Json please include Remote.Linq.Newtonsoft.Json in your project and used the provided extension method to configure JsonSerializerSettings:

using Newtonsoft.Json;
using Remote.Linq;
…
JsonSerializerSettings serializerSettings = new JsonSerializerSettings().ConfigureRemoteLinq();

Support Expression.Block

Hi,
first Thanks for your fantanstic work.
For a project I need to Serialize an ExpressionTree that contains Expression.Block. Ist there any way I can easy extend your Translator to support this, without compiling remote linq by myself?

ToRemoteLinqExpression swallows Take in SelectMany

The following test fails

var result = (
    from p in _productQueryable.Take(1)
    from c in _categoryQueryable.Take(1)
    select new { p, c }).ToList();

result.Count().ShouldBe(1);
Shouldly.ShouldAssertException
result.Count()
    should be
1
    but was
2

In the debugger I can see that the second Take(1) is gone after ToRemoteLinqExpression.

StackOverflow for ConstantTypeExpression

Hi,
the following line kills with StackOverflowException:
Expression<Func<Type>> transform = () => typeof(T); LambdaExpression expression = transform.ToRemoteLinqExpression();
I'm currently using 5.5.0 alpha 003 as I need some other features from this version. Version 5.4.1 semms to have the same issue.
Am I making some mistake?
Thanks for your help

FieldAccessException on composing a LINQ (to EF) query on the frontend side

Hi!

After adding this member to my EF (6.2, code-first) entity class:

public const string MY_CONST = "Something";

I run into a FieldAccessException on the client side on composing the Linq query for remote execution thrown by the Aqua.Dynamic.DynamicObjectMapper, I tried to add the [NonSerialize] attribute to that member but that didn't help. For the time being I changed the const into a static member and the error is gone, but that is not exactly what I want.

How can I avoid this exception or does the Aqua lib need an update?

Thanks!
Karlo

PS:
Ok, I just found that by adding the [Unmapped] attribute to the public const member I can avoid this problem. However this introduces an extra dependency (on the Aqua.dll) to my .dll that holds the EF entity classes. Wouldn't it make sense to treat const's as Unmapped anyway?

InvalidOperationException: variable of anonymous type referenced from scope '', but it is not defined

5.5.0-beta-001

_productQueryable
    .Select(p => new {ids = _productQueryable.Select(pp => pp.Id)})
    .Select(a => a.ids.Count())
    .ToList();

fails with

System.InvalidOperationException
variable 'a' of type '<>f__AnonymousType1`1[System.Linq.IQueryable`1[System.Int32]]' referenced from scope '', but it is not defined
   at System.Linq.Expressions.Compiler.VariableBinder.Reference(ParameterExpression node, VariableStorageKind storage)
   at System.Linq.Expressions.Compiler.VariableBinder.VisitParameter(ParameterExpression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitMember(MemberExpression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1 nodes)
   at System.Linq.Expressions.Compiler.VariableBinder.VisitLambda[T](Expression`1 node)
   at System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda, DebugInfoGenerator debugInfoGenerator)
   at System.Linq.Expressions.Expression`1.Compile()
   at Remote.Linq.ExpressionVisitors.SystemExpressionReWriter.RemoteQueryableVisitor.VisitMemberAccess(MemberExpression node)
   at Remote.Linq.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionVisitors.ExpressionVisitorBase.VisitExpressionList[T](ReadOnlyCollection`1 original)
   at Remote.Linq.ExpressionVisitors.ExpressionVisitorBase.VisitMethodCall(MethodCallExpression node)
   at Remote.Linq.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionVisitors.ExpressionVisitorBase.VisitLambda(LambdaExpression node)
   at Remote.Linq.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionVisitors.ExpressionVisitorBase.VisitUnary(UnaryExpression node)
   at Remote.Linq.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionVisitors.ExpressionVisitorBase.VisitExpressionList[T](ReadOnlyCollection`1 original)
   at Remote.Linq.ExpressionVisitors.ExpressionVisitorBase.VisitMethodCall(MethodCallExpression node)
   at Remote.Linq.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionVisitors.SystemExpressionReWriter.RemoteQueryableVisitor.Simplify(Expression expression)
   at Remote.Linq.ExpressionVisitors.SystemExpressionReWriter.SimplifyIncorporationOfRemoteQueryables(Expression expression)
   at Remote.Linq.DynamicQuery.RemoteQueryProvider`1.TranslateExpression(Expression expression, ITypeResolver typeResolver)
   at Remote.Linq.DynamicQuery.RemoteQueryProvider`1.Execute[TResult](Expression expression)
   at Remote.Linq.DynamicQuery.RemoteQueryable`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)

Not really a bugreport this time but a HUGE CREDIT for your hard work!

Hey @6bee!

Today I finally pushed the result of about 10 months of work on my own project InfoCarrier.Core which I'm sure will interest you as well. Let me express my deepest gratitude to you for your amazing libraries Remote.Linq and aqua-core which I'm confidently relying on in my project. I would also be very thankful to you if you find a moment to have a brief look at InfoCarrier.Core and provide some feedback and fair criticism. If you wish we could arrange a Skype confo.

Best Regards,
Alexander Zabluda (aka @azabluda)

EnumerableQuery should not translate to QueryableResourceDescriptor

Test Should_query_products_filterd_using_local_variables_closure_inline_mix fails if I pass a list of Ids as queryable

[Fact]
public void Should_query_products_filterd_using_local_variables_closure_inline_mix()
{
    IEnumerable<int?> listOfIds = new List<int?>() { null, 1, 11, 111 }.AsQueryable(); // <=== EnumerableQuery
    int oneId = 10;
    var query =
        from p in _productQueryable
        where listOfIds.Contains(p.Id) || new List<string> { "Truck", "Bicycle" }.Contains(p.Name) || p.Id % 3 == 0 || p.Id == oneId
        select p;
    var result = query.ToArray();
    result.Count().ShouldBe(4);
}
System.Collections.Generic.KeyNotFoundException
The given key was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Remote.Linq.Tests.RemoteQueryable.QueryTestData.Store.Get(Type type)
   at Remote.Linq.ExpressionVisitors.QueryableResourceVisitor.ResourceDescriptorVisitor.VisitConstant(ConstantExpression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.VisitExpressionList(List`1 original)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.VisitNew(NewExpression newExpression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.VisitMemberAccess(MemberExpression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.<VisitMethodCall>b__22_0(Expression i)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.VisitMethodCall(MethodCallExpression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.VisitBinary(BinaryExpression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.VisitBinary(BinaryExpression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.VisitBinary(BinaryExpression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.VisitLambda(LambdaExpression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.VisitUnary(UnaryExpression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.<VisitMethodCall>b__22_0(Expression i)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.VisitMethodCall(MethodCallExpression expression)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionVisitorBase.Visit(Expression expression)
   at Remote.Linq.ExpressionVisitors.QueryableResourceVisitor.ResourceDescriptorVisitor.ReplaceResourceDescriptorsByQueryable(Expression expression)
   at Remote.Linq.ExpressionVisitors.QueryableResourceVisitor.ReplaceResourceDescriptorsByQueryable[T](T expression, Func`2 provider, ITypeResolver typeResolver)
   at Remote.Linq.ExpressionVisitors.RemoteExpressionReWriter.ReplaceResourceDescriptorsByQueryable[T](T expression, ITypeResolver typeResolver, Func`2 provider)
   at Remote.Linq.Expressions.ExpressionExtensions.PrepareForExecution(Expression expression, Func`2 queryableProvider, ITypeResolver typeResolver)
   at Remote.Linq.Expressions.ExpressionExtensions.Execute(Expression expression, Func`2 queryableProvider, ITypeResolver typeResolver, Func`2 resultPorjector, IDynamicObjectMapper mapper, Func`2 setTypeInformation)
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.<>c__DisplayClass9_1.<.ctor>b__0(Expression expression)
   at Remote.Linq.DynamicQuery.RemoteQueryProvider`1.Execute[TResult](Expression expression)
   at Remote.Linq.DynamicQuery.RemoteQueryable`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Remote.Linq.Tests.RemoteQueryable.When_running_query.Should_query_products_filterd_using_local_variables_closure_inline_mix()

I think it should be sufficient to simply prevent translation of values of type System.Linq.EnumerableQuery to QueryableResourceDescriptor.

Bug. Deserialized ConditionalExpression in the "if False"part does not work.

ConditionalExpression in the "if False"part does not work after deserialization. That is, the alternative condition "else"does not work.

How to reproduce the bug on Remote.Linq version 6.1.0 in project on .Net Core 2.2:

           var condition = Expression.MakeBinary(ExpressionType.LessThan, Expression.Constant(5), Expression.Constant(2));
           ConditionalExpression ifThenElseExpression = Expression.IfThenElse(
                condition,
                Expression.Call(
                    null,
                    typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }),
                    Expression.Constant("The condition is true.")
                ),
                Expression.Call(
                    null,
                    typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }),
                    Expression.Constant("The condition is false.")
                )
            );
            var lambdaExpression = Expression.Lambda<Action>(ifThenElseExpression);
            lambdaExpression.Compile()(); // will be printed: "The condition is false."
            var remote = ifThenElseExpression.ToRemoteLinqExpression();
            var received = remote.ToLinqExpression();
            lambdaExpression = Expression.Lambda<Action>(received);
            lambdaExpression.Compile()(); // nothing will be printed :(

How to fix it or compensate?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.