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

Commit 6124b8b

Browse files
committed
Support separate From() Expressions in SqlExpressions, previously coupled to Select()
1 parent d26485b commit 6124b8b

File tree

2 files changed

+88
-5
lines changed

2 files changed

+88
-5
lines changed

src/ServiceStack.OrmLite/Expressions/SqlExpression.cs

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99

1010
namespace ServiceStack.OrmLite
1111
{
12-
public abstract class SqlExpression<T>
12+
public abstract class SqlExpression<T> : ISqlExpression
1313
{
1414
private Expression<Func<T, bool>> underlyingExpression;
1515
private List<string> orderByProperties = new List<string>();
1616
private string selectExpression = string.Empty;
17+
private string fromExpression = null;
1718
private string whereExpression;
1819
private string groupBy = string.Empty;
1920
private string havingExpression;
@@ -47,6 +48,7 @@ protected virtual SqlExpression<T> CopyTo(SqlExpression<T> to)
4748
to.underlyingExpression = underlyingExpression;
4849
to.orderByProperties = orderByProperties;
4950
to.selectExpression = selectExpression;
51+
to.fromExpression = fromExpression;
5052
to.whereExpression = whereExpression;
5153
to.groupBy = groupBy;
5254
to.havingExpression = havingExpression;
@@ -112,6 +114,30 @@ public virtual SqlExpression<T> SelectDistinct<TKey>(Expression<Func<T, TKey>> f
112114
return this;
113115
}
114116

117+
public virtual SqlExpression<T> From(string tables)
118+
{
119+
if (string.IsNullOrEmpty(tables))
120+
{
121+
FromExpression = null;
122+
}
123+
else
124+
{
125+
tables.SqlVerifyFragment();
126+
var singleTable = tables.ToLower().IndexOfAny("join", ",") >= 0;
127+
FromExpression = singleTable
128+
? " \nFROM " + OrmLiteConfig.DialectProvider.GetQuotedTableName(tables)
129+
: " \nFROM " + tables;
130+
}
131+
132+
return this;
133+
}
134+
135+
public virtual SqlExpression<T> From<Table>()
136+
{
137+
FromExpression = " \nFROM " + OrmLiteConfig.DialectProvider.GetQuotedTableName(typeof(Table).GetModelDefinition());
138+
return this;
139+
}
140+
115141
public virtual SqlExpression<T> Where()
116142
{
117143
if (underlyingExpression != null) underlyingExpression = null; //Where() clears the expression
@@ -457,6 +483,9 @@ public virtual string ToSelectStatement()
457483
var sql = new StringBuilder();
458484

459485
sql.Append(SelectExpression);
486+
487+
sql.Append(FromExpression);
488+
460489
sql.Append(string.IsNullOrEmpty(WhereExpression) ?
461490
"" :
462491
"\n" + WhereExpression);
@@ -492,6 +521,17 @@ public string SelectExpression
492521
}
493522
}
494523

524+
public string FromExpression
525+
{
526+
get
527+
{
528+
return string.IsNullOrEmpty(fromExpression)
529+
? " \nFROM " + OrmLiteConfig.DialectProvider.GetQuotedTableName(modelDef)
530+
: fromExpression;
531+
}
532+
set { fromExpression = value; }
533+
}
534+
495535
public string WhereExpression
496536
{
497537
get
@@ -1035,13 +1075,11 @@ protected static object GetQuotedFalseValue()
10351075

10361076
private void BuildSelectExpression(string fields, bool distinct)
10371077
{
1038-
1039-
selectExpression = string.Format("SELECT {0}{1} \nFROM {2}",
1078+
selectExpression = string.Format("SELECT {0}{1}",
10401079
(distinct ? "DISTINCT " : ""),
10411080
(string.IsNullOrEmpty(fields) ?
10421081
OrmLiteConfig.DialectProvider.GetColumnNames(modelDef) :
1043-
fields),
1044-
OrmLiteConfig.DialectProvider.GetQuotedTableName(modelDef));
1082+
fields));
10451083
}
10461084

10471085
public IList<string> GetAllFields()
@@ -1263,6 +1301,11 @@ protected virtual object VisitColumnAccessMethod(MethodCallExpression m)
12631301
}
12641302
}
12651303

1304+
public interface ISqlExpression
1305+
{
1306+
string ToSelectStatement();
1307+
}
1308+
12661309
public class PartialSqlString
12671310
{
12681311
public PartialSqlString(string text)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System.Data;
2+
using NUnit.Framework;
3+
using ServiceStack.OrmLite.Tests.Shared;
4+
5+
namespace ServiceStack.OrmLite.Tests.Expression
6+
{
7+
public class Band
8+
{
9+
public string Name { get; set; }
10+
public int PersonId { get; set; }
11+
}
12+
13+
public class FromExpressionTests : ExpressionsTestBase
14+
{
15+
public void Init(IDbConnection db)
16+
{
17+
db.DropAndCreateTable<Person>();
18+
db.DropAndCreateTable<Band>();
19+
20+
db.InsertAll(Person.Rockstars);
21+
22+
db.Insert(new Band { Name = "The Doors", PersonId = 3 });
23+
db.Insert(new Band { Name = "Nirvana", PersonId = 4 });
24+
}
25+
26+
[Test]
27+
public void Can_select_from_custom_FROM_expression()
28+
{
29+
using (var db = OpenDbConnection())
30+
{
31+
Init(db);
32+
33+
var results = db.Select(db.From<Person>("Person INNER JOIN Band ON Person.Id = Band.PersonId"));
34+
35+
Assert.That(results.Count, Is.EqualTo(2));
36+
Assert.That(results.ConvertAll(x => x.FirstName), Is.EquivalentTo(new[] { "Kurt", "Jim" }));
37+
}
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)