Giga Meta
Giga Meta

Reputation: 319

Expression tree check equality c#

For my school project, I need to build an small ORM, so I'm not trying to reinvent the wheel. I want to create an expression lambda and compare the values like the WHERE clause in LINQ to SQL. I want to get the left param property, so for example "Name" and compare it to a string, but I keep getting the exception and can't figure out how to solve it.

System.InvalidOperationException: 'variable 'source' of type 'Project.People' referenced from scope '', but it is not defined

/

class People
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program
{
    public static List<People> CreatePeople()
    {
        return new List<People>()
        {
            new People { Id = 1, Age = 10, Name = "A"},
            new People { Id = 2, Age = 11, Name = "B"},
            new People { Id = 3, Age = 12, Name = "C"},
            new People { Id = 4, Age = 13, Name = "D"},
            new People { Id = 5, Age = 14, Name = "E"}
        };
    }

    static void Main(string[] args)
    {
        var people = CreatePeople().AsQueryable();
        var test = people.ORMWhere(x => x.Name == "A");
    }
}

public class Extensions
{
    public static IQueryable<TResult> ORMWhere<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> predicate)
    {
        var body = predicate.Body as BinaryExpression;
        var parameeter = Expression.Parameter(typeof(TSource), "source");
        switch (body.NodeType)
        {
            case ExpressionType.Equal:
                var left = body.Left.GetExpressionName();
                var right = body.Right.GetExpressionValue();
                var expr = Expression.Property(parameeter, left);
                var lol = Expression.Equal(
                    expr,
                    Expression.Constant(right)
                );
                var okk = Expression.Lambda(lol).Compile().DynamicInvoke();
                break;
            default:
                throw new Exception();

        }
        return null;
    }

Upvotes: 0

Views: 244

Answers (1)

Mario Welzig
Mario Welzig

Reputation: 618

The lambda you create doesn't have any parameters and you never pass any People instances to it. This should evaluate to true:

var okk = Expression.Lambda(lol, parameeter)
                    .Compile()
                    .DynamicInvoke(new People { Name = "A" });

The expression tree you're compiling is effectively equivalent to this code:

() => (source.Name == "A")

And since the parameter is missing, source is undeclared.

Upvotes: 4

Related Questions