2014-04-07 63 views
0

因此,我通過創建一個很好的數據訪問層與我自己和C#開心。Lambda到SQL的翻譯

我有以下的方法進行並行運動的簡單表達一個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轉換爲字符串是

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,任何建議或代碼?

+2

你知道Linq2SQL和Linq2Entities這樣做嗎? – Magnus

+2

不要'ToString'表達式樹,但*實際上完全處理*樹。 – poke

+0

我不認爲你應該使用表達式樹的字符串表示。表達式樹的整個觀點是解析已經完成了,並且你得到了一棵樹。順便說一句,我認爲從表達式樹生成代碼是一項相當複雜的任務,而不是在下午要做的事情。 – Stilgar

回答

3

我管理,我得到的輸出..來解決它自己,呵呵呵這裏是我做的,不是finnished但但也許別人可能會發現它有用

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

,謝謝,非常非常好,但是如何以parentes命令並持有parentes語句??/ – Mohsen

+0

非常酷。你有什麼知識,我可以在java中實現這樣的東西嗎? – webMan1

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] 
+0

我已經做到了,我的輸出是「System.Linq.Enumerable + WhereSelectListIterator'2 [ReflectionExampleByDonaldJansen.BussinessLogic.Person,System.String]」 –

+0

如果您的集合僅來自實體數據模型,那麼你將獲得Equalent SQL查詢... –

+0

我認爲你的集合是IEnumerable類型的。 –