Lambda到SQL的翻译

时间:2014-04-07 12:37:44

标签: 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);

我得到以下结果

UPDATE People SET Name='Donald',Surname='Jansen' WHERE (PersonID = 1)

但现在如果我做以下

var m = p.BuildUpdateQuerry(people[0], x => x.PersonID == people[0].PersonID);

我得到以下结果

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

我用来将Lambda转换为String的方法是

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

到目前为止,这是非常基本和真正的乐趣,但我不知道如何克服这个XDXD,任何建议或代码?

3 个答案:

答案 0 :(得分:4)

我自己设法解决了,hehehe这里是我做的,还没有完成,但也许其他人可能会发现它有用

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

答案 1 :(得分:0)

您可以使用System.Linq的内置扩展方法将lambda表达式转换为SQL。 请参阅下面的代码......

var Enames = emp.Employees.Select ( e => e.EmployeeName );
Console.WriteLine ( Enames );

我得到的输出..

SELECT
[Extent1].[EmployeeName] AS [EmployeeName]
FROM [dbo].[Employee] AS [Extent1]

答案 2 :(得分:0)

我遇到了同样的问题,不久前就开始解决。看看LambdaSql。 目前,它包含select子句和where过滤器的基本方案。设置字段已经支持,在其中可以进行分组,分组,排序,联接,嵌套查询。稍后将支持插入,更新和删除。

示例:

var qry = new SqlSelect
(
    new SqlSelect<Person>()
        .AddFields(p => p.Id, p => p.Name)
        .Where(SqlFilter<Person>.From(p => p.Name).EqualTo("Sergey"))
    , new SqlAlias("inner")
).AddFields<Person>(p => p.Name);

Console.WriteLine(qry.ParametricSql);
Console.WriteLine("---");
Console.WriteLine(string.Join("; ", qry.Parameters
    .Select(p => $"Name = {p.ParameterName}, Value = {p.Value}")));

输出:

SELECT
    inner.Name
FROM
(
    SELECT
        pe.Id, pe.Name
    FROM
        Person pe
    WHERE
        pe.Name = @w0
) AS inner
---
Name = @w0, Value = Sergey

在此处https://github.com/Serg046/LambdaSql

查看更多