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

Commit 9e6c8cb

Browse files
committed
Count Extension method
Count Extension with Expression support.
1 parent 6f1017d commit 9e6c8cb

File tree

8 files changed

+147
-7
lines changed

8 files changed

+147
-7
lines changed

src/ServiceStack.OrmLite/Expressions/ReadConnectionExtensions.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,5 +176,24 @@ public static TKey GetScalar<T, TKey>(this IDbConnection dbConn, Expression<Func
176176
{
177177
return dbConn.Exec(dbCmd => dbCmd.GetScalar(field, predicate));
178178
}
179+
180+
public static long Count<T>(this IDbConnection dbConn, SqlExpressionVisitor<T> expression)
181+
where T : new()
182+
{
183+
return dbConn.Exec(dbCmd => dbCmd.Count(expression));
184+
}
185+
186+
public static long Count<T>(this IDbConnection dbConn, Expression<Func<T, bool>> expression)
187+
where T : new()
188+
{
189+
return dbConn.Exec(dbCmd => dbCmd.Count(expression));
190+
}
191+
192+
public static long Count<T>(this IDbConnection dbConn)
193+
where T : new()
194+
{
195+
SqlExpressionVisitor<T> expression = OrmLiteConfig.DialectProvider.ExpressionVisitor<T>();
196+
return dbConn.Exec(dbCmd => dbCmd.Count(expression));
197+
}
179198
}
180199
}

src/ServiceStack.OrmLite/Expressions/ReadExtensions.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,30 @@ public static TKey GetScalar<T,TKey>(this IDbCommand dbCmd,Expression<Func<T, TK
131131
string sql = ev.ToSelectStatement();
132132
return dbCmd.GetScalar<TKey>(sql);
133133
}
134+
135+
public static long Count<T>(this IDbCommand dbCmd)
136+
where T : new()
137+
{
138+
SqlExpressionVisitor<T> expression = OrmLiteConfig.DialectProvider.ExpressionVisitor<T>();
139+
string sql = expression.ToCountStatement();
140+
return dbCmd.GetScalar<long>(sql);
141+
}
142+
143+
public static long Count<T>(this IDbCommand dbCmd, SqlExpressionVisitor<T> expression)
144+
where T : new()
145+
{
146+
string sql = expression.ToCountStatement();
147+
return dbCmd.GetScalar<long>(sql);
148+
}
149+
150+
public static long Count<T>(this IDbCommand dbCmd, Expression<Func<T, bool>> predicate)
151+
where T : new()
152+
{
153+
var ev = OrmLiteConfig.DialectProvider.ExpressionVisitor<T>();
154+
ev.Where(predicate);
155+
string sql = ev.ToCountStatement();
156+
return dbCmd.GetScalar<long>(sql);
157+
}
134158

135159
private static T ConvertTo<T>(IDataReader dataReader)
136160
where T : new()

src/ServiceStack.OrmLite/Expressions/SqlExpressionVisitor.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,11 @@ public virtual string ToSelectStatement()
449449
return ApplyPaging(sql.ToString());
450450
}
451451

452+
public virtual string ToCountStatement()
453+
{
454+
return OrmLiteConfig.DialectProvider.ToCountStatement(modelDef.ModelType, WhereExpression, null);
455+
}
456+
452457
public string SelectExpression
453458
{
454459
get
@@ -1168,13 +1173,13 @@ protected virtual object VisitColumnAccessMethod(MethodCallExpression m)
11681173
statement = string.Format("lower({0})", quotedColName);
11691174
break;
11701175
case "StartsWith":
1171-
statement = string.Format("upper({0}) like {1} ", quotedColName, OrmLiteConfig.DialectProvider.GetQuotedParam(args[0].ToString().ToUpper() + "%"));
1176+
statement = string.Format("upper({0}) like {1} ", quotedColName, OrmLiteConfig.DialectProvider.GetQuotedParam(args[0].ToString().ToUpper() + "%"));
11721177
break;
11731178
case "EndsWith":
1174-
statement = string.Format("upper({0}) like {1}", quotedColName, OrmLiteConfig.DialectProvider.GetQuotedParam("%" + args[0].ToString().ToUpper()));
1179+
statement = string.Format("upper({0}) like {1}", quotedColName, OrmLiteConfig.DialectProvider.GetQuotedParam("%" + args[0].ToString().ToUpper()));
11751180
break;
11761181
case "Contains":
1177-
statement = string.Format("upper({0}) like {1}", quotedColName, OrmLiteConfig.DialectProvider.GetQuotedParam("%" + args[0].ToString().ToUpper() + "%"));
1182+
statement = string.Format("upper({0}) like {1}", quotedColName, OrmLiteConfig.DialectProvider.GetQuotedParam("%" + args[0].ToString().ToUpper() + "%"));
11781183
break;
11791184
case "Substring":
11801185
var startIndex = Int32.Parse(args[0].ToString()) + 1;

src/ServiceStack.OrmLite/IOrmLiteDialectProvider.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ string ToSelectFromProcedureStatement(object fromObjWithProperties,
8989
string sqlFilter,
9090
params object[] filterParams);
9191

92+
string ToCountStatement(Type fromTableType, string sqlFilter, params object[] filterParams);
93+
9294
string ToExecuteProcedureStatement(object objWithProperties);
9395

9496
string ToCreateTableStatement(Type tableType);

src/ServiceStack.OrmLite/OrmLiteDialectProviderBase.cs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ public virtual string GetQuotedValue(object value, Type fieldType)
296296
{
297297
if (TypeSerializer.CanCreateFromString(fieldType))
298298
{
299-
return OrmLiteConfig.DialectProvider.GetQuotedParam(TypeSerializer.SerializeToString(value));
299+
return OrmLiteConfig.DialectProvider.GetQuotedParam(TypeSerializer.SerializeToString(value));
300300
}
301301

302302
throw new NotSupportedException(
@@ -313,15 +313,15 @@ public virtual string GetQuotedValue(object value, Type fieldType)
313313
return ((decimal)value).ToString(CultureInfo.InvariantCulture);
314314

315315
return ShouldQuoteValue(fieldType)
316-
? OrmLiteConfig.DialectProvider.GetQuotedParam(value.ToString())
316+
? OrmLiteConfig.DialectProvider.GetQuotedParam(value.ToString())
317317
: value.ToString();
318318
}
319319

320320
public abstract IDbConnection CreateConnection(string filePath, Dictionary<string, string> options);
321321

322-
public virtual string GetQuotedParam(string paramValue)
322+
public virtual string GetQuotedParam(string paramValue)
323323
{
324-
return "'" + paramValue.Replace("'", "''") + "'";
324+
return "'" + paramValue.Replace("'", "''") + "'";
325325
}
326326

327327
public virtual string GetQuotedTableName(ModelDefinition modelDef)
@@ -406,6 +406,33 @@ public virtual string GetColumnDefinition(string fieldName, Type fieldType,
406406

407407
public abstract long GetLastInsertId(IDbCommand command);
408408

409+
public virtual string ToCountStatement(Type fromTableType, string sqlFilter, params object[] filterParams)
410+
{
411+
var sql = new StringBuilder();
412+
const string SelectStatement = "SELECT ";
413+
var modelDef = fromTableType.GetModelDefinition();
414+
var isFullSelectStatement =
415+
!string.IsNullOrEmpty(sqlFilter)
416+
&& sqlFilter.TrimStart().StartsWith(SelectStatement, StringComparison.OrdinalIgnoreCase);
417+
418+
if (isFullSelectStatement) return (filterParams != null ? sqlFilter.SqlFormat(filterParams) : sqlFilter);
419+
420+
sql.AppendFormat("SELECT {0} FROM {1}", "COUNT(*)",
421+
GetQuotedTableName(modelDef));
422+
if (!string.IsNullOrEmpty(sqlFilter))
423+
{
424+
sqlFilter = filterParams != null ? sqlFilter.SqlFormat(filterParams) : sqlFilter;
425+
if ((!sqlFilter.StartsWith("ORDER ", StringComparison.InvariantCultureIgnoreCase)
426+
&& !sqlFilter.StartsWith("LIMIT ", StringComparison.InvariantCultureIgnoreCase))
427+
&& (!sqlFilter.StartsWith("WHERE ", StringComparison.InvariantCultureIgnoreCase)))
428+
{
429+
sql.Append(" WHERE ");
430+
}
431+
sql.Append(" " + sqlFilter);
432+
}
433+
return sql.ToString();
434+
}
435+
409436
public virtual string ToSelectStatement(Type tableType, string sqlFilter, params object[] filterParams)
410437
{
411438
const string SelectStatement = "SELECT ";
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using ServiceStack.OrmLite;
6+
using System.IO;
7+
using System.Data;
8+
using ServiceStack.DataAnnotations;
9+
using ServiceStack.Common.Utils;
10+
using ServiceStack.OrmLite.Sqlite;
11+
12+
namespace SqliteExpressionsTest
13+
{
14+
15+
public class CountTest
16+
{
17+
private static string GetFileConnectionString()
18+
{
19+
var connectionString = "~/db.sqlite".MapAbsolutePath();
20+
if (File.Exists(connectionString))
21+
File.Delete(connectionString);
22+
23+
return connectionString;
24+
}
25+
26+
27+
public static void Test()
28+
{
29+
OrmLiteConfig.DialectProvider = SqliteOrmLiteDialectProvider.Instance;
30+
31+
var path = GetFileConnectionString();
32+
if (File.Exists(path))
33+
File.Delete(path);
34+
//using (IDbConnection db = ":memory:".OpenDbConnection())
35+
using (IDbConnection db = path.OpenDbConnection())
36+
using (IDbCommand dbCmd = db.CreateCommand())
37+
{
38+
dbCmd.CreateTable<User>(true);
39+
40+
dbCmd.Insert(new User { Id = 1, Name = "A", CreatedDate = DateTime.Now, UserDataId = 5, UserServiceId = 8 });
41+
dbCmd.Insert(new User { Id = 2, Name = "B", CreatedDate = DateTime.Now, UserDataId = 5, UserServiceId = 9 });
42+
dbCmd.Insert(new User { Id = 3, Name = "B", CreatedDate = DateTime.Now });
43+
44+
SqlExpressionVisitor<User> ev = OrmLiteConfig.DialectProvider.ExpressionVisitor<User>();
45+
46+
var count1 = dbCmd.Count<User>(x => x.Id == 1);
47+
var count2 = dbCmd.Count<User>(ev.Where(x => x.Id == 2));
48+
var count3 = dbCmd.Count<User>();
49+
50+
count1 = db.Count<User>(x => x.Id == 1);
51+
count2 = db.Count<User>(ev.Where(x => x.Id == 2));
52+
count3 = db.Count<User>();
53+
54+
}
55+
56+
File.Delete(path);
57+
}
58+
}
59+
}

src/SqliteExpressionsTest/Program.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ public static void Main (string[] args)
5151
Console.WriteLine("Ignored Field Select Test");
5252
IgnoredFieldSelectTest.Test();
5353

54+
Console.WriteLine("Count Test");
55+
CountTest.Test();
56+
5457
OrmLiteConfig.DialectProvider = SqliteOrmLiteDialectProvider.Instance;
5558
SqlExpressionVisitor<Author> ev = OrmLiteConfig.DialectProvider.ExpressionVisitor<Author>();
5659

src/SqliteExpressionsTest/SqliteExpressionsTest.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
</Reference>
6767
</ItemGroup>
6868
<ItemGroup>
69+
<Compile Include="CountTest.cs" />
6970
<Compile Include="IgnoredFieldSelectTest.cs" />
7071
<Compile Include="JoinTest.cs" />
7172
<Compile Include="Program.cs" />

0 commit comments

Comments
 (0)