表达式树检查相等性 c#

Expression tree check equality c#

对于我的学校项目,我需要构建一个小型 ORM,所以我不想重新发明轮子。我想创建一个表达式 lambda,并将 LINQ 中的 WHERE 子句之类的值与 SQL 进行比较。我想获取左参数 属性,例如“Name”并将其与字符串进行比较,但我一直收到异常并且无法弄清楚如何解决它。

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;
    }

您创建的 lambda 没有任何参数,您永远不会将任何 People 实例传递给它。这应该评估为真:

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

您正在编译的表达式树实际上等效于此代码:

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

并且由于缺少参数,source 未声明。