Lambda 到 SQL 的转换

Don*_*sen 0 c# lambda

因此,我通过创建一个漂亮的数据访问层来享受自己和 C# 带来的乐趣。

我有以下方法将简单表达式转换为 SQL where 子句,但它仅适用于以下内容

var people = DataAccessLayer.SelectAllPeople(x => x.Name == "Donald");
//Do some changes to the list
people[0].Surname = "Jansen"
var m = p.BuildUpdateQuerry(people[0], x => x.PersonID == 1);
Run Code Online (Sandbox Code Playgroud)

我得到以下结果

UPDATE People SET Name='Donald',Surname='Jansen' WHERE (PersonID = 1)
Run Code Online (Sandbox Code Playgroud)

但现在如果我执行以下操作

var m = p.BuildUpdateQuerry(people[0], x => x.PersonID == people[0].PersonID);
Run Code Online (Sandbox Code Playgroud)

我得到以下结果

UPDATE People SET Name='Donald',Surname='Jansen' WHERE (PersonID = value(ReflectionExampleByDonaldJansen.Program+<>c__DisplayClass0).people.get_Item(0).PersonID)
Run Code Online (Sandbox Code Playgroud)

我用来将 Lambda 转换为字符串的方法是

public static string GetWhereClause<T>(Expression<Func<T, bool>> expression)
{
    var name = expression.Parameters[0].ToString();
    var body = expression.Body.ToString().Replace("\"", "'");
    body = body.Replace("OrElse", "OR");
    body = body.Replace("AndAlso", "AND");
    body = body.Replace("==", "=");
    body = body.Replace("!=", "<>");
    body = body.Replace(string.Format("{0}.", name), "");
    return body;
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,这是非常基本且真正有趣的事情,但我不知道如何克服这个 XDXD,有什么建议或代码吗?

Don*_*sen 5

我自己设法解决了这个问题,呵呵,这就是我所做的,尚未完成,但也许其他人可能会发现它有用

    public static string GetWhereClause<T>(Expression<Func<T, bool>> expression)
    {
        return GetValueAsString(expression.Body);
    }

    public static string GetValueAsString(Expression expression)
    {
        var value = "";
        var equalty = "";
        var left = GetLeftNode(expression);
        var right = GetRightNode(expression);
        if (expression.NodeType == ExpressionType.Equal)
        {
            equalty = "=";
        }
        if (expression.NodeType == ExpressionType.AndAlso)
        {
            equalty = "AND";
        }
        if (expression.NodeType == ExpressionType.OrElse)
        {
            equalty = "OR";
        }
        if (expression.NodeType == ExpressionType.NotEqual)
        {
            equalty = "<>";
        }
        if (left is MemberExpression)
        {
            var leftMem = left as MemberExpression;
            value = string.Format("({0}{1}'{2}')", leftMem.Member.Name, equalty, "{0}");
        }
        if (right is ConstantExpression)
        {
            var rightConst = right as ConstantExpression;
            value = string.Format(value, rightConst.Value);
        }
        if (right is MemberExpression)
        {
            var rightMem = right as MemberExpression;
            var rightConst = rightMem.Expression as ConstantExpression;
            var member = rightMem.Member.DeclaringType;
            var type = rightMem.Member.MemberType;
            var val = member.GetField(rightMem.Member.Name).GetValue(rightConst.Value);
            value = string.Format(value, val);
        }
        if (value == "")
        {
            var leftVal = GetValueAsString(left);
            var rigthVal = GetValueAsString(right);
            value = string.Format("({0} {1} {2})", leftVal, equalty, rigthVal);
        }
        return value;
    }

    private static Expression GetLeftNode(Expression expression)
    {
        dynamic exp = expression;
        return ((Expression)exp.Left);
    }

    private static Expression GetRightNode(Expression expression)
    {
        dynamic exp = expression;
        return ((Expression)exp.Right);
    }
Run Code Online (Sandbox Code Playgroud)