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

Commit 97e1c05

Browse files
committed
Merge pull request #284 from mishfit/master
Fixed Filtering with Anonymous Types and Aliased Field Names
2 parents 9f0b0e8 + b3e4e8d commit 97e1c05

File tree

3 files changed

+67
-10
lines changed

3 files changed

+67
-10
lines changed

src/ServiceStack.OrmLite/OrmLiteReadExtensions.cs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -215,18 +215,20 @@ private static void SetFilter<T>(IDbCommand dbCmd, string name, object value)
215215

216216
public static void SetFilters<T>(this IDbCommand dbCmd, object anonType, bool excludeNulls)
217217
{
218-
SetParameters(dbCmd, anonType, excludeNulls);
218+
SetParameters<T>(dbCmd, anonType, excludeNulls);
219219

220220
dbCmd.CommandText = GetFilterSql<T>(dbCmd);
221221
}
222222

223-
private static void SetParameters(this IDbCommand dbCmd, object anonType, bool excludeNulls)
223+
private static void SetParameters<T>(this IDbCommand dbCmd, object anonType, bool excludeNulls)
224224
{
225225
dbCmd.Parameters.Clear();
226226
lastQueryType = null;
227227
if (anonType == null) return;
228228

229-
var pis = anonType.GetType().GetSerializableProperties();
229+
var pis = anonType.GetType().GetSerializableProperties();
230+
ModelDefinition model = ModelDefinition<T>.Definition;
231+
230232
foreach (var pi in pis)
231233
{
232234
var mi = pi.GetGetMethod();
@@ -235,8 +237,15 @@ private static void SetParameters(this IDbCommand dbCmd, object anonType, bool e
235237
var value = mi.Invoke(anonType, new object[0]);
236238
if (excludeNulls && value == null) continue;
237239

240+
238241
var p = dbCmd.CreateParameter();
239-
p.ParameterName = pi.Name;
242+
243+
FieldDefinition targetField = model.FieldDefinitions.FirstOrDefault(f => string.Equals(f.Name, pi.Name));
244+
if (targetField != null && !string.IsNullOrEmpty(targetField.Alias))
245+
p.ParameterName = targetField.Alias;
246+
else
247+
p.ParameterName = pi.Name;
248+
240249
p.DbType = OrmLiteConfig.DialectProvider.GetColumnDbType(pi.PropertyType);
241250
p.Direction = ParameterDirection.Input;
242251
p.Value = value;
@@ -328,7 +337,7 @@ internal static T QuerySingle<T>(this IDbCommand dbCmd, string sql, object anonT
328337
{
329338
if (IsScalar<T>()) return QueryScalar<T>(dbCmd, sql, anonType);
330339

331-
dbCmd.SetParameters(anonType, true);
340+
dbCmd.SetParameters<T>(anonType, true);
332341
dbCmd.CommandText = OrmLiteConfig.DialectProvider.ToSelectStatement(typeof(T), sql);
333342

334343
using (var dbReader = dbCmd.ExecuteReader())
@@ -359,7 +368,7 @@ internal static List<T> Where<T>(this IDbCommand dbCmd, object anonType)
359368

360369
internal static List<T> Query<T>(this IDbCommand dbCmd, string sql, object anonType = null)
361370
{
362-
if (anonType != null) dbCmd.SetParameters(anonType, true);
371+
if (anonType != null) dbCmd.SetParameters<T>(anonType, true);
363372
dbCmd.CommandText = OrmLiteConfig.DialectProvider.ToSelectStatement(typeof(T), sql);
364373

365374
using (var dbReader = dbCmd.ExecuteReader())
@@ -389,7 +398,7 @@ internal static T QueryScalar<T>(this IDbCommand dbCmd, object anonType)
389398

390399
internal static T QueryScalar<T>(this IDbCommand dbCmd, string sql, object anonType = null)
391400
{
392-
if (anonType != null) dbCmd.SetParameters(anonType, true);
401+
if (anonType != null) dbCmd.SetParameters<T>(anonType, true);
393402
dbCmd.CommandText = OrmLiteConfig.DialectProvider.ToSelectStatement(typeof(T), sql);
394403

395404
using (var dbReader = dbCmd.ExecuteReader())
@@ -398,7 +407,7 @@ internal static T QueryScalar<T>(this IDbCommand dbCmd, string sql, object anonT
398407

399408
internal static List<T> SqlList<T>(this IDbCommand dbCmd, string sql, object anonType = null)
400409
{
401-
if (anonType != null) dbCmd.SetParameters(anonType, true);
410+
if (anonType != null) dbCmd.SetParameters<T>(anonType, true);
402411
dbCmd.CommandText = sql;
403412

404413
using (var dbReader = dbCmd.ExecuteReader())
@@ -420,7 +429,7 @@ internal static List<T> SqlList<T>(this IDbCommand dbCmd, string sql, Dictionary
420429

421430
internal static T SqlScalar<T>(this IDbCommand dbCmd, string sql, object anonType = null)
422431
{
423-
if (anonType != null) dbCmd.SetParameters(anonType, true);
432+
if (anonType != null) dbCmd.SetParameters<T>(anonType, true);
424433
dbCmd.CommandText = sql;
425434

426435
using (var dbReader = dbCmd.ExecuteReader())
@@ -446,7 +455,7 @@ internal static List<T> ByExampleWhere<T>(this IDbCommand dbCmd, object anonType
446455

447456
internal static List<T> QueryByExample<T>(this IDbCommand dbCmd, string sql, object anonType = null)
448457
{
449-
if (anonType != null) dbCmd.SetParameters(anonType, true);
458+
if (anonType != null) dbCmd.SetParameters<T>(anonType, true);
450459
dbCmd.CommandText = OrmLiteConfig.DialectProvider.ToSelectStatement(typeof(T), sql);
451460

452461
using (var dbReader = dbCmd.ExecuteReader())

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
<Compile Include="SqlBuilderTests.cs" />
148148
<Compile Include="SqlServerProviderTests.cs" />
149149
<Compile Include="TypeWithByteArrayFieldTests.cs" />
150+
<Compile Include="UseCase\AliasedFieldUseCase.cs" />
150151
<Compile Include="UseCase\CustomerOrdersUseCase.cs" />
151152
<Compile Include="UseCase\SchemaUseCase.cs" />
152153
<Compile Include="UseCase\ShardingUseCase.cs" />
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Data;
4+
using NUnit.Framework;
5+
using ServiceStack.DataAnnotations;
6+
7+
namespace ServiceStack.OrmLite.Tests.UseCase
8+
{
9+
[TestFixture]
10+
public class AliasedFieldUseCase
11+
{
12+
[TestFixtureSetUp]
13+
public void TestFixtureSetup() {
14+
OrmLiteConfig.DialectProvider = SqliteDialect.Provider;
15+
}
16+
17+
public class Foo
18+
{
19+
[Alias("SOME_COLUMN_NAME")]
20+
public string Bar { get; set; }
21+
}
22+
23+
[Test]
24+
public void CanResolveAliasedFieldNameInAnonymousType()
25+
{
26+
using (IDbConnection db = ":memory:".OpenDbConnection())
27+
{
28+
db.CreateTable<Foo>(false);
29+
30+
db.Insert(new Foo { Bar = "some_value" });
31+
db.Insert(new Foo { Bar = "a totally different value" });
32+
db.Insert(new Foo { Bar = "whatever" });
33+
34+
// the original classes property name is used to create the anonymous type
35+
List<Foo> foos = db.Where<Foo>(new { Bar = "some_value" });
36+
37+
Assert.That(foos, Has.Count.EqualTo(1));
38+
39+
// the aliased column name is used to create the anonymous type
40+
foos = db.Where<Foo>(new { SOME_COLUMN_NAME = "some_value" });
41+
42+
Assert.That(foos, Has.Count.EqualTo(1));
43+
}
44+
}
45+
46+
}
47+
}

0 commit comments

Comments
 (0)