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

Commit 97d20b8

Browse files
committed
Handle when selecting against an interface in a generic method
1 parent 4ac30c2 commit 97d20b8

File tree

2 files changed

+70
-3
lines changed

2 files changed

+70
-3
lines changed

src/ServiceStack.OrmLite/Expressions/SqlExpression.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1713,6 +1713,15 @@ protected virtual bool IsParameterOrConvertAccess(Expression e)
17131713
return CheckExpressionForTypes(e, new[] { ExpressionType.Parameter, ExpressionType.Convert });
17141714
}
17151715

1716+
/// <summary>
1717+
/// Check whether the expression is a constant expression to determine
1718+
/// whether we should use the expression value instead of Column Name
1719+
/// </summary>
1720+
protected virtual bool IsConstantExpression(Expression e)
1721+
{
1722+
return CheckExpressionForTypes(e, new[] { ExpressionType.Constant });
1723+
}
1724+
17161725
protected bool CheckExpressionForTypes(Expression e, ExpressionType[] types)
17171726
{
17181727
while (e != null)
@@ -1826,7 +1835,11 @@ protected virtual object VisitMemberAccess(MemberExpression m)
18261835
}
18271836

18281837
if (IsParameterOrConvertAccess(m))
1829-
return GetMemberExpression(m);
1838+
{
1839+
// We don't want to use the Column Name for constant expressions unless we're in a Sql. method call
1840+
if (inSqlMethodCall || !IsConstantExpression(m))
1841+
return GetMemberExpression(m);
1842+
}
18301843
}
18311844

18321845
return CachedExpressionCompiler.Evaluate(m);
@@ -2213,10 +2226,18 @@ protected virtual bool IsColumnAccess(MethodCallExpression m)
22132226
&& IsJoinedTable(exp.Expression.Type);
22142227
}
22152228

2229+
private bool inSqlMethodCall = false;
2230+
22162231
protected virtual object VisitMethodCall(MethodCallExpression m)
22172232
{
22182233
if (m.Method.DeclaringType == typeof(Sql))
2219-
return VisitSqlMethodCall(m);
2234+
{
2235+
var hold = inSqlMethodCall;
2236+
inSqlMethodCall = true;
2237+
var ret = VisitSqlMethodCall(m);
2238+
inSqlMethodCall = hold;
2239+
return ret;
2240+
}
22202241

22212242
if (IsStaticArrayMethod(m))
22222243
return VisitStaticArrayMethodCall(m);

tests/ServiceStack.OrmLite.Tests/Issues/SelectAliasIssue.cs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using System.Linq;
1+
using System;
2+
using System.Data;
3+
using System.Linq;
24
using NUnit.Framework;
35
using ServiceStack.DataAnnotations;
46
using ServiceStack.Text;
@@ -15,6 +17,33 @@ public class AddressAudit
1517
public int AddressId { get; set; }
1618
}
1719

20+
public interface ILookup
21+
{
22+
Guid Id { get; set; }
23+
string Name { get; }
24+
}
25+
26+
public class TestLookup : ILookup
27+
{
28+
public Guid Id { get; set; }
29+
public string Name { get; set; }
30+
}
31+
32+
public static class TestLookupExtensions
33+
{
34+
public static T Lookup<T>(this IDbConnection db, T record) where T : ILookup, new()
35+
{
36+
var lkp = db.Single<T>(r => r.Name == record.Name);
37+
if (lkp != null)
38+
return lkp;
39+
40+
if (record.Id == Guid.Empty)
41+
record.Id = Guid.NewGuid();
42+
db.Insert(record);
43+
return record;
44+
}
45+
}
46+
1847
[TestFixtureOrmLite]
1948
public class SelectAliasIssue : OrmLiteProvidersTestBase
2049
{
@@ -40,5 +69,22 @@ public void Does_populate_table_with_Aliases_having_same_name_as_alternative_fie
4069
row.PrintDump();
4170
}
4271
}
72+
73+
[Test]
74+
public void Select_against_interface_in_generic_method()
75+
{
76+
using (var db = OpenDbConnection())
77+
{
78+
db.CreateTable<TestLookup>();
79+
80+
var newRecord = new TestLookup {Name = "new"};
81+
82+
var lkp = db.Single<TestLookup>(r => r.Name == newRecord.Name);
83+
84+
85+
var lookup = db.Lookup(newRecord);
86+
Assert.That(lookup.Id != Guid.Empty);
87+
}
88+
}
4389
}
4490
}

0 commit comments

Comments
 (0)