Skip to content

Instantly share code, notes, and snippets.

@Artur2
Created February 13, 2020 07:32
Show Gist options
  • Save Artur2/e2663777efab795522a812fac226994d to your computer and use it in GitHub Desktop.
Save Artur2/e2663777efab795522a812fac226994d to your computer and use it in GitHub Desktop.
Sample of basic entry point to relinq provider
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Remotion.Linq.Clauses;
using Remotion.Linq.Clauses.ExpressionTreeVisitors;
using Remotion.Linq.Parsing.Structure;
namespace Remotion.Linq.Sample
{
// The item type that our data source will return.
public class SampleDataSourceItem
{
public string Name { get; set; }
public string Description { get; set; }
}
internal class SampleQueryable<T> : QueryableBase<T>
{
public SampleQueryable(IQueryParser queryParser, IQueryExecutor executor)
: base(new DefaultQueryProvider(typeof(SampleQueryable<>), queryParser, executor))
{
}
public SampleQueryable(IQueryProvider provider, Expression expression)
: base(provider, expression)
{
}
}
internal class SampleQueryExecutor : IQueryExecutor
{
// Set up a proeprty that will hold the current item being enumerated.
public SampleDataSourceItem Current { get; private set; }
public IEnumerable<T> ExecuteCollection<T>(QueryModel queryModel)
{
// Create an expression that returns the current item when invoked.
Expression currentItemExpression = Expression.Property(Expression.Constant(this), "Current");
// Now replace references like the "i" in "select i" that refers to the "i" in "from i in items"
var mapping = new QuerySourceMapping();
mapping.AddMapping(queryModel.MainFromClause, currentItemExpression);
queryModel.TransformExpressions(e =>
ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences(e, mapping, true));
// Create a lambda that takes our SampleDataSourceItem and passes it through the select clause
// to produce a type of T. (T may be SampleDataSourceItem, in which case this is an identity function.)
var currentItemProperty = Expression.Parameter(typeof(SampleDataSourceItem));
var projection = Expression.Lambda<Func<SampleDataSourceItem, T>>(queryModel.SelectClause.Selector, currentItemProperty);
var projector = projection.Compile();
// Pretend we're getting SampleDataSourceItems from somewhere...
for (var i = 0; i < 10; i++)
{
// Set the current item so currentItemExpression can access it.
Current = new SampleDataSourceItem
{
Name = "Name " + i,
Description = "This describes the item in position " + i
};
// Use the projector to convert (if necessary) the current item to what is being selected and return it.
yield return projector(Current);
}
}
public T ExecuteSingle<T>(QueryModel queryModel, bool returnDefaultWhenEmpty)
{
var sequence = ExecuteCollection<T>(queryModel);
return returnDefaultWhenEmpty ? sequence.SingleOrDefault() : sequence.Single();
}
public T ExecuteScalar<T>(QueryModel queryModel)
{
// We'll get to this one later...
throw new NotImplementedException();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment