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

Commit 7557710

Browse files
committed
Add tracer bullet impl of supporting parameterized queries in SqlExpression<T>
1 parent badb73c commit 7557710

File tree

8 files changed

+108
-5
lines changed

8 files changed

+108
-5
lines changed

src/ServiceStack.OrmLite/Expressions/ReadExpressionCommandExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ internal static List<T> Select<T>(this IDbCommand dbCmd, SqlExpression<T> expres
3535
{
3636
string sql = expression.SelectInto<T>();
3737

38-
return dbCmd.ExprConvertToList<T>(sql);
38+
return dbCmd.ExprConvertToList<T>(sql, expression.Params);
3939
}
4040

4141
internal static List<T> Select<T>(this IDbCommand dbCmd, Expression<Func<T, bool>> predicate)

src/ServiceStack.OrmLite/Expressions/SqlExpression.cs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Data;
45
using System.Linq;
56
using System.Reflection;
67
using System.Text;
@@ -31,6 +32,7 @@ public abstract partial class SqlExpression<T> : ISqlExpression
3132
public bool PrefixFieldWithTableName { get; set; }
3233
public bool WhereStatementWithoutWhereString { get; set; }
3334
public IOrmLiteDialectProvider DialectProvider { get; set; }
35+
public List<IDbDataParameter> Params { get; set; }
3436

3537
protected string Sep
3638
{
@@ -43,6 +45,7 @@ public SqlExpression(IOrmLiteDialectProvider dialectProvider)
4345
PrefixFieldWithTableName = false;
4446
WhereStatementWithoutWhereString = false;
4547
DialectProvider = dialectProvider;
48+
Params = new List<IDbDataParameter>();
4649
tableDefs.Add(modelDef);
4750
}
4851

@@ -68,6 +71,7 @@ protected virtual SqlExpression<T> CopyTo(SqlExpression<T> to)
6871
to.modelDef = modelDef;
6972
to.PrefixFieldWithTableName = PrefixFieldWithTableName;
7073
to.WhereStatementWithoutWhereString = WhereStatementWithoutWhereString;
74+
to.Params = new List<IDbDataParameter>(Params);
7175
return to;
7276
}
7377

@@ -1148,8 +1152,6 @@ protected virtual object VisitParameter(ParameterExpression p)
11481152
return p.Name;
11491153
}
11501154

1151-
public Dictionary<string, object> Params = new Dictionary<string, object>();
1152-
11531155
protected virtual object VisitConstant(ConstantExpression c)
11541156
{
11551157
if (c.Value == null)
@@ -1606,10 +1608,36 @@ protected virtual object VisitColumnAccessMethod(MethodCallExpression m)
16061608
}
16071609
return new PartialSqlString(statement);
16081610
}
1611+
1612+
public IDbDataParameter CreateParam(string name,
1613+
object value = null,
1614+
ParameterDirection direction = ParameterDirection.Input,
1615+
DbType? dbType = null)
1616+
{
1617+
var p = new OrmLiteDataParameter {
1618+
ParameterName = DialectProvider.GetParam(name),
1619+
Direction = direction
1620+
};
1621+
if (value != null)
1622+
{
1623+
p.Value = value;
1624+
p.DbType = DialectProvider.GetColumnDbType(value.GetType());
1625+
}
1626+
if (dbType != null)
1627+
p.DbType = dbType.Value;
1628+
1629+
if (p.DbType == DbType.String)
1630+
p.Size = DialectProvider.DefaultStringLength;
1631+
1632+
return p;
1633+
}
1634+
16091635
}
16101636

16111637
public interface ISqlExpression
16121638
{
1639+
List<IDbDataParameter> Params { get; }
1640+
16131641
string ToSelectStatement();
16141642
string SelectInto<TModel>();
16151643
}
@@ -1640,5 +1668,18 @@ public EnumMemberAccess(string text, Type enumType)
16401668
public Type EnumType { get; private set; }
16411669
}
16421670

1671+
public class OrmLiteDataParameter : IDbDataParameter
1672+
{
1673+
public DbType DbType { get; set; }
1674+
public ParameterDirection Direction { get; set; }
1675+
public bool IsNullable { get; set; }
1676+
public string ParameterName { get; set; }
1677+
public string SourceColumn { get; set; }
1678+
public DataRowVersion SourceVersion { get; set; }
1679+
public object Value { get; set; }
1680+
public byte Precision { get; set; }
1681+
public byte Scale { get; set; }
1682+
public int Size { get; set; }
1683+
}
16431684
}
16441685

src/ServiceStack.OrmLite/JoinSqlBuilder.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Data;
34
using System.Linq;
45
using System.Linq.Expressions;
56
using System.Text;
@@ -603,6 +604,8 @@ public string ToSql()
603604
return SelectInto<TNewPoco>();
604605
}
605606

607+
public List<IDbDataParameter> Params { get; private set; }
608+
606609
public string ToSelectStatement()
607610
{
608611
return SelectInto<TNewPoco>();

src/ServiceStack.OrmLite/OrmLiteResultsFilterExtensions.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,36 @@ public static IList ConvertToList(this IDbCommand dbCmd, Type refType, string sq
8989
}
9090
}
9191

92-
internal static List<T> ExprConvertToList<T>(this IDbCommand dbCmd, string sql = null)
92+
public static IDbDataParameter PopulateWith(this IDbDataParameter to, IDbDataParameter from)
93+
{
94+
to.DbType = from.DbType;
95+
to.Direction = from.Direction;
96+
to.ParameterName = from.ParameterName;
97+
to.SourceColumn = from.SourceColumn;
98+
to.SourceVersion = from.SourceVersion;
99+
to.Value = from.Value;
100+
to.Precision = from.Precision;
101+
to.Scale = from.Scale;
102+
to.Size = from.Size;
103+
104+
return to;
105+
}
106+
107+
internal static List<T> ExprConvertToList<T>(this IDbCommand dbCmd, string sql = null, IEnumerable<IDbDataParameter> sqlParams = null)
93108
{
94109
if (sql != null)
95110
dbCmd.CommandText = sql;
96111

112+
if (sqlParams != null)
113+
{
114+
foreach (var sqlParam in sqlParams)
115+
{
116+
var p = dbCmd.CreateParameter();
117+
p.PopulateWith(sqlParam);
118+
dbCmd.Parameters.Add(p);
119+
}
120+
}
121+
97122
if (OrmLiteConfig.ResultsFilter != null)
98123
{
99124
return OrmLiteConfig.ResultsFilter.GetList<T>(dbCmd);

src/ServiceStack.OrmLite/SqlBuilder.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Data;
34
using System.Linq;
45
using System.Reflection;
56
using System.Reflection.Emit;
67
using System.Text.RegularExpressions;
78
using System.Threading;
89
using ServiceStack.Text;
10+
using PropertyAttributes = System.Reflection.PropertyAttributes;
911

1012
namespace ServiceStack.OrmLite
1113
{
@@ -215,6 +217,8 @@ void ResolveSql()
215217
public string RawSql { get { ResolveSql(); return rawSql; } }
216218
public object Parameters { get { ResolveSql(); return parameters; } }
217219

220+
public List<IDbDataParameter> Params { get; private set; }
221+
218222
public string ToSelectStatement()
219223
{
220224
return RawSql;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using NUnit.Framework;
2+
using ServiceStack.Text;
3+
4+
namespace ServiceStack.OrmLite.Tests.Expression
5+
{
6+
[TestFixture]
7+
public class SqlExpressionParamTests : OrmLiteTestBase
8+
{
9+
[Test]
10+
public void Can_add_DbParam_to_SqlExpression()
11+
{
12+
using (var db = OpenDbConnection())
13+
{
14+
SqlExpressionTests.InitLetters(db);
15+
16+
var q = db.From<LetterFrequency>()
17+
.UnsafeWhere("Letter = {0}".Fmt(db.GetDialectProvider().GetParam("p1")));
18+
19+
q.Params.Add(q.CreateParam("p1", "B"));
20+
21+
var results = db.Select(q);
22+
23+
results.PrintDump();
24+
25+
Assert.That(results.Count, Is.EqualTo(2));
26+
}
27+
}
28+
}
29+
}

tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public class LetterStat
3535

3636
public class SqlExpressionTests : ExpressionsTestBase
3737
{
38-
private static void InitLetters(IDbConnection db)
38+
public static void InitLetters(IDbConnection db)
3939
{
4040
db.DropAndCreateTable<LetterFrequency>();
4141

tests/ServiceStack.OrmLite.Tests/ServiceStack.OrmLite.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
<Compile Include="Expression\FromExpressionTests.cs" />
127127
<Compile Include="Expression\GenericTableExpressions.cs" />
128128
<Compile Include="Expression\MethodExpressionTests.cs" />
129+
<Compile Include="Expression\SqlExpressionParamTests.cs" />
129130
<Compile Include="Expression\SqlExpressionTests.cs" />
130131
<Compile Include="Expression\SelectExpressionTests.cs" />
131132
<Compile Include="Issues\ComplexJoinWithAlias.cs" />

0 commit comments

Comments
 (0)