Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit a4be4b7

Browse files
authored
Merge pull request #524 from OlegNadymov/master
Added support Concat string in SqlExpression
2 parents 221fafb + bbaeafc commit a4be4b7

File tree

7 files changed

+97
-1
lines changed

7 files changed

+97
-1
lines changed

src/ServiceStack.OrmLite.Firebird/FirebirdSqlExpression.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.Generic;
12
using System.Linq.Expressions;
23

34
namespace ServiceStack.OrmLite.Firebird
@@ -29,6 +30,11 @@ protected override object VisitColumnAccessMethod(MethodCallExpression m)
2930
}
3031
return new PartialSqlString(statement);
3132
}
33+
34+
protected override PartialSqlString ToConcatPartialString(List<object> args)
35+
{
36+
return new PartialSqlString(string.Join(" || ", args));
37+
}
3238
}
3339
}
3440

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1-
namespace ServiceStack.OrmLite.MySql
1+
using System.Collections.Generic;
2+
3+
namespace ServiceStack.OrmLite.MySql
24
{
35
public class MySqlExpression<T> : SqlExpression<T>
46
{
57
public MySqlExpression(IOrmLiteDialectProvider dialectProvider)
68
: base(dialectProvider) {}
9+
10+
protected override PartialSqlString ToConcatPartialString(List<object> args)
11+
{
12+
return new PartialSqlString(string.Format("CONCAT({0})", string.Join(", ", args)));
13+
}
714
}
815
}

src/ServiceStack.OrmLite.Oracle/OracleSqlExpression.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ public override SqlExpression<T> OrderByRandom()
5252
{
5353
return base.OrderBy("dbms_random.value");
5454
}
55+
56+
protected override PartialSqlString ToConcatPartialString(List<object> args)
57+
{
58+
return new PartialSqlString(string.Join(" || ", args));
59+
}
5560
}
5661
}
5762

src/ServiceStack.OrmLite.PostgreSQL/PostgreSqlExpression.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.Generic;
12
using System.Linq;
23

34
namespace ServiceStack.OrmLite.PostgreSQL
@@ -24,6 +25,11 @@ public override SqlExpression<T> OrderByRandom()
2425
{
2526
return base.OrderBy("RANDOM()");
2627
}
28+
29+
protected override PartialSqlString ToConcatPartialString(List<object> args)
30+
{
31+
return new PartialSqlString(string.Join(" || ", args));
32+
}
2733
}
2834

2935
}

src/ServiceStack.OrmLite.Sqlite/SqliteExpression.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Linq.Expressions;
34

45
namespace ServiceStack.OrmLite.Sqlite
@@ -76,5 +77,10 @@ public override SqlExpression<T> OrderByRandom()
7677
{
7778
return base.OrderBy("random()");
7879
}
80+
81+
protected override PartialSqlString ToConcatPartialString(List<Object> args)
82+
{
83+
;return new PartialSqlString(String.Join(" || ", args));
84+
}
7985
}
8086
}

src/ServiceStack.OrmLite/Expressions/SqlExpression.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,9 @@ protected virtual object VisitBinary(BinaryExpression b)
13641364
else if (operand == "<>" && right.ToString().Equals("null", StringComparison.OrdinalIgnoreCase))
13651365
operand = "is not";
13661366

1367+
if (operand == "+" && b.Left.Type == typeof(string) && b.Right.Type == typeof(string))
1368+
return BuildConcatExpression(new List<object>() {left, right});
1369+
13671370
VisitFilter(operand, originalLeft, originalRight, ref left, ref right);
13681371

13691372
switch (operand)
@@ -1739,6 +1742,9 @@ protected virtual object VisitMethodCall(MethodCallExpression m)
17391742
if (IsColumnAccess(m))
17401743
return VisitColumnAccessMethod(m);
17411744

1745+
if (IsStaticStringMethod(m))
1746+
return VisitStaticStringMethodCall(m);
1747+
17421748
return CachedExpressionCompiler.Evaluate(m);
17431749
}
17441750

@@ -1994,6 +2000,44 @@ private object ToInPartialString(Expression memberExpr, object quotedColName)
19942000
return new PartialSqlString(statement);
19952001
}
19962002

2003+
private bool IsStaticStringMethod(MethodCallExpression m)
2004+
{
2005+
if (m.Object == null && m.Method.Name == "Concat")
2006+
{
2007+
return true;
2008+
}
2009+
2010+
return false;
2011+
}
2012+
2013+
protected virtual object VisitStaticStringMethodCall(MethodCallExpression m)
2014+
{
2015+
switch (m.Method.Name)
2016+
{
2017+
case "Concat":
2018+
var args = VisitExpressionList(m.Arguments);
2019+
return BuildConcatExpression(args);
2020+
2021+
default:
2022+
throw new NotSupportedException();
2023+
}
2024+
}
2025+
2026+
private PartialSqlString BuildConcatExpression(List<object> args)
2027+
{
2028+
for (int i = 0; i < args.Count; i++)
2029+
{
2030+
if (args[i] as PartialSqlString == null)
2031+
args[i] = ConvertToParam(args[i]);
2032+
}
2033+
return ToConcatPartialString(args);
2034+
}
2035+
2036+
protected virtual PartialSqlString ToConcatPartialString(List<object> args)
2037+
{
2038+
return new PartialSqlString(String.Join(" + ", args));
2039+
}
2040+
19972041
protected virtual object VisitSqlMethodCall(MethodCallExpression m)
19982042
{
19992043
List<object> args = this.VisitInSqlExpressionList(m.Arguments);

tests/ServiceStack.OrmLite.Tests/ExpressionVisitorTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,28 @@ public void Can_Where_using_filter_with_ToString()
462462
Assert.That(target.Count, Is.EqualTo(3));
463463
}
464464

465+
[Test]
466+
public void Can_Where_using_filter_with_Concat()
467+
{
468+
string filterText = "asdf";
469+
int filterInt = 10;
470+
471+
System.Linq.Expressions.Expression<Func<TestType, bool>> filter = x => String.Concat(x.TextCol, x.NullableIntCol.ToString()) == filterText + filterInt;
472+
var q = Db.From<TestType>().Where(filter);
473+
var target = Db.Select(q);
474+
Assert.That(target.Count, Is.EqualTo(1));
475+
476+
filter = x => String.Concat(x.TextCol, ".", x.NullableIntCol.ToString()) == filterText + "." + filterInt;
477+
q = Db.From<TestType>().Where(filter);
478+
target = Db.Select(q);
479+
Assert.That(target.Count, Is.EqualTo(1));
480+
481+
filter = x => x.TextCol + "." + x.NullableIntCol.ToString() == filterText + "." + filterInt;
482+
q = Db.From<TestType>().Where(filter);
483+
target = Db.Select(q);
484+
Assert.That(target.Count, Is.EqualTo(1));
485+
}
486+
465487
private int MethodReturningInt(int val)
466488
{
467489
return val;

0 commit comments

Comments
 (0)