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

Commit 3370cf3

Browse files
committed
Expand support for UpdateOnly APIs
1 parent 1588a4b commit 3370cf3

14 files changed

+235
-43
lines changed

src/ServiceStack.OrmLite/Async/WriteExpressionCommandExtensionsAsync.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,23 @@ internal static Task<int> UpdateOnlyAsync<T>(this IDbCommand dbCmd, T model, Sql
1515
return dbCmd.ExecNonQueryAsync(token);
1616
}
1717

18-
internal static Task<int> UpdateOnlyAsync<T, TKey>(this IDbCommand dbCmd, T obj,
19-
Expression<Func<T, TKey>> onlyFields,
20-
Expression<Func<T, bool>> where,
18+
internal static Task<int> UpdateOnlyAsync<T>(this IDbCommand dbCmd, T obj,
19+
Expression<Func<T, object>> onlyFields,
20+
Expression<Func<T, bool>> where,
21+
CancellationToken token)
22+
{
23+
if (onlyFields == null)
24+
throw new ArgumentNullException("onlyFields");
25+
26+
var q = dbCmd.GetDialectProvider().SqlExpression<T>();
27+
q.Update(onlyFields);
28+
q.Where(where);
29+
return dbCmd.UpdateOnlyAsync(obj, q, token);
30+
}
31+
32+
internal static Task<int> UpdateOnlyAsync<T>(this IDbCommand dbCmd, T obj,
33+
string[] onlyFields,
34+
Expression<Func<T, bool>> where,
2135
CancellationToken token)
2236
{
2337
if (onlyFields == null)

src/ServiceStack.OrmLite/Expressions/SqlExpression.cs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -810,28 +810,37 @@ public virtual SqlExpression<T> ClearLimits()
810810
/// Fields to be updated.
811811
/// </summary>
812812
/// <param name='updatefields'>
813-
/// IList<string> containing Names of properties to be updated
813+
/// List&lt;string&gt; containing Names of properties to be updated
814814
/// </param>
815815
public virtual SqlExpression<T> Update(List<string> updateFields)
816816
{
817817
this.UpdateFields = updateFields;
818818
return this;
819819
}
820820

821+
/// <summary>
822+
/// Fields to be updated.
823+
/// </summary>
824+
/// <param name='updatefields'>
825+
/// IEnumerable&lt;string&gt; containing Names of properties to be updated
826+
/// </param>
827+
public virtual SqlExpression<T> Update(IEnumerable<string> updateFields)
828+
{
829+
this.UpdateFields = new List<string>(updateFields);
830+
return this;
831+
}
832+
821833
/// <summary>
822834
/// Fields to be updated.
823835
/// </summary>
824836
/// <param name='fields'>
825-
/// x=> x.SomeProperty1 or x=> new{ x.SomeProperty1, x.SomeProperty2}
837+
/// x=> x.SomeProperty1 or x=> new { x.SomeProperty1, x.SomeProperty2 }
826838
/// </param>
827-
/// <typeparam name='TKey'>
828-
/// objectWithProperties
829-
/// </typeparam>
830-
public virtual SqlExpression<T> Update<TKey>(Expression<Func<T, TKey>> fields)
839+
public virtual SqlExpression<T> Update(Expression<Func<T, object>> fields)
831840
{
832841
sep = string.Empty;
833842
useFieldName = false;
834-
UpdateFields = Visit(fields).ToString().Split(',').ToList();
843+
this.UpdateFields = fields.GetFieldNames().ToList();
835844
return this;
836845
}
837846

src/ServiceStack.OrmLite/Expressions/WriteExpressionCommandExtensions.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,19 @@ internal static int UpdateOnly<T>(this IDbCommand dbCmd, T obj,
4545
return dbCmd.UpdateOnly(obj, q);
4646
}
4747

48+
internal static int UpdateOnly<T>(this IDbCommand dbCmd, T obj,
49+
string[] onlyFields = null,
50+
Expression<Func<T, bool>> where = null)
51+
{
52+
if (onlyFields == null)
53+
throw new ArgumentNullException("onlyFields");
54+
55+
var q = dbCmd.GetDialectProvider().SqlExpression<T>();
56+
q.Update(onlyFields);
57+
q.Where(where);
58+
return dbCmd.UpdateOnly(obj, q);
59+
}
60+
4861
internal static int UpdateOnly<T>(this IDbCommand dbCmd,
4962
Expression<Func<T>> updateFields,
5063
SqlExpression<T> q)

src/ServiceStack.OrmLite/OrmLiteWriteCommandExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,8 @@ internal static int DeleteNonDefaults<T>(this IDbCommand dbCmd, T filter)
459459

460460
internal static int Delete<T>(this IDbCommand dbCmd, T[] objs)
461461
{
462-
if (objs.Length == 0) return 0;
462+
if (objs.Length == 0)
463+
return 0;
463464

464465
return DeleteAll(dbCmd, objs);
465466
}

src/ServiceStack.OrmLite/OrmLiteWriteExpressionsApi.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ public static int UpdateOnly<T>(this IDbConnection dbConn,
6060
///
6161
/// db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName);
6262
/// UPDATE "Person" SET "FirstName" = 'JJ'
63+
///
64+
/// db.UpdateOnly(new Person { FirstName = "JJ", Age = 27 }, p => new { p.FirstName, p.Age );
65+
/// UPDATE "Person" SET "FirstName" = 'JJ', "Age" = 27
6366
/// </summary>
6467
public static int UpdateOnly<T>(this IDbConnection dbConn, T obj,
6568
Expression<Func<T, object>> onlyFields = null,
@@ -68,6 +71,19 @@ public static int UpdateOnly<T>(this IDbConnection dbConn, T obj,
6871
return dbConn.Exec(dbCmd => dbCmd.UpdateOnly(obj, onlyFields, where));
6972
}
7073

74+
/// <summary>
75+
/// Update record, updating only fields specified in updateOnly that matches the where condition (if any), E.g:
76+
///
77+
/// db.UpdateOnly(new Person { FirstName = "JJ" }, new[]{ "FirstName" }, p => p.LastName == "Hendrix");
78+
/// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix')
79+
/// </summary>
80+
public static int UpdateOnly<T>(this IDbConnection dbConn, T obj,
81+
string[] onlyFields,
82+
Expression<Func<T, bool>> where = null)
83+
{
84+
return dbConn.Exec(dbCmd => dbCmd.UpdateOnly(obj, onlyFields, where));
85+
}
86+
7187
/// <summary>
7288
/// Update record, updating only fields specified in updateOnly that matches the where condition (if any), E.g:
7389
/// Numeric fields generates an increment sql which is usefull to increment counters, etc...

src/ServiceStack.OrmLite/OrmLiteWriteExpressionsApiAsync.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ public static Task<int> UpdateOnlyAsync<T>(this IDbConnection dbConn,
6666
/// db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName);
6767
/// UPDATE "Person" SET "FirstName" = 'JJ'
6868
/// </summary>
69-
public static Task<int> UpdateOnlyAsync<T, TKey>(this IDbConnection dbConn, T obj,
70-
Expression<Func<T, TKey>> onlyFields = null,
69+
public static Task<int> UpdateOnlyAsync<T>(this IDbConnection dbConn, T obj,
70+
Expression<Func<T, object>> onlyFields = null,
7171
Expression<Func<T, bool>> where = null,
7272
CancellationToken token = default(CancellationToken))
7373
{
@@ -93,6 +93,20 @@ public static Task<int> UpdateAddAsync<T>(this IDbConnection dbConn,
9393
return dbConn.Exec(dbCmd => dbCmd.UpdateAddAsync(updateFields, dbCmd.GetDialectProvider().SqlExpression<T>().Where(where)));
9494
}
9595

96+
/// <summary>
97+
/// Update record, updating only fields specified in updateOnly that matches the where condition (if any), E.g:
98+
///
99+
/// db.UpdateOnly(new Person { FirstName = "JJ" }, new[]{ "FirstName" }, p => p.LastName == "Hendrix");
100+
/// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix')
101+
/// </summary>
102+
public static Task<int> UpdateOnlyAsync<T>(this IDbConnection dbConn, T obj,
103+
string[] onlyFields,
104+
Expression<Func<T, bool>> where = null,
105+
CancellationToken token = default(CancellationToken))
106+
{
107+
return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyAsync(obj, onlyFields, where, token));
108+
}
109+
96110
/// <summary>
97111
/// Update record, updating only fields specified in updateOnly that matches the where condition (if any), E.g:
98112
/// Numeric fields generates an increment sql which is usefull to increment counters, etc...

tests/ServiceStack.OrmLite.Tests/ApiSqlServerTests.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -259,21 +259,27 @@ public void API_SqlServer_Examples()
259259
db.UpdateAll(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } });
260260
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id"));
261261

262-
db.Update(new Person { Id = 1, FirstName = "JJ", Age = 27 }, x => x.LastName == "Hendrix");
262+
db.Update(new Person { Id = 1, FirstName = "JJ", Age = 27 }, where: x => x.LastName == "Hendrix");
263263
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Id\"=@1, \"FirstName\"=@2, \"LastName\"=@3, \"Age\"=@4 WHERE (\"LastName\" = @0)"));
264264

265-
db.Update<Person>(new { FirstName = "JJ" }, x => x.LastName == "Hendrix");
265+
db.Update<Person>(new { FirstName = "JJ" }, where: x => x.LastName == "Hendrix");
266266
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@1 WHERE (\"LastName\" = @0)"));
267267

268268
db.UpdateNonDefaults(new Person { FirstName = "JJ" }, x => x.LastName == "Hendrix");
269269
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@1 WHERE (\"LastName\" = @0)"));
270270

271-
db.UpdateOnly(new Person { FirstName = "JJ" }, x => x.FirstName);
271+
db.UpdateOnly(() => new Person { FirstName = "JJ" });
272272
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@0"));
273273

274-
db.UpdateOnly(() => new Person { FirstName = "JJ" });
274+
db.UpdateOnly(new Person { FirstName = "JJ" }, x => x.FirstName);
275275
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@0"));
276276

277+
db.UpdateOnly(new Person { FirstName = "JJ", Age = 27 }, p => new { p.FirstName, p.Age });
278+
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@0, \"Age\"=@1"));
279+
280+
db.UpdateOnly(new Person { FirstName = "JJ", Age = 27 }, new[] { "FirstName", "Age" });
281+
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@0, \"Age\"=@1"));
282+
277283
db.UpdateOnly(new Person { FirstName = "JJ" }, x => x.FirstName, x => x.LastName == "Hendrix");
278284
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@1 WHERE (\"LastName\" = @0)"));
279285

@@ -283,9 +289,6 @@ public void API_SqlServer_Examples()
283289
db.UpdateOnly(() => new Person { FirstName = "JJ" }, db.From<Person>().Where(p => p.LastName == "Hendrix"));
284290
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@1 WHERE (\"LastName\" = @0)"));
285291

286-
db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, db.From<Person>().Update(x => x.FirstName));
287-
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@0"));
288-
289292
db.UpdateOnly(new Person { FirstName = "JJ" }, db.From<Person>().Update(x => x.FirstName).Where(x => x.FirstName == "Jimi"));
290293
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@1 WHERE (\"FirstName\" = @0)"));
291294

tests/ServiceStack.OrmLite.Tests/ApiSqliteTests.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ public void API_Sqlite_Examples()
264264
db.UpdateAll(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } });
265265
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id"));
266266

267-
db.Update(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix");
267+
db.Update(new Person { Id = 1, FirstName = "JJ", Age = 27 }, where: p => p.LastName == "Hendrix");
268268
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Id\"=@1, \"FirstName\"=@2, \"LastName\"=@3, \"Age\"=@4 WHERE (\"LastName\" = @0)"));
269269

270270
db.Update<Person>(new { FirstName = "JJ" }, where: p => p.LastName == "Hendrix");
@@ -273,12 +273,18 @@ public void API_Sqlite_Examples()
273273
db.UpdateNonDefaults(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix");
274274
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@1 WHERE (\"LastName\" = @0)"));
275275

276-
db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName);
276+
db.UpdateOnly(() => new Person { FirstName = "JJ" });
277277
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@0"));
278278

279-
db.UpdateOnly(() => new Person { FirstName = "JJ" });
279+
db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName);
280280
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@0"));
281281

282+
db.UpdateOnly(new Person { FirstName = "JJ", Age = 27 }, p => new { p.FirstName, p.Age });
283+
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@0, \"Age\"=@1"));
284+
285+
db.UpdateOnly(new Person { FirstName = "JJ", Age = 27 }, new[] { "FirstName", "Age" });
286+
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@0, \"Age\"=@1"));
287+
282288
db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix");
283289
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@1 WHERE (\"LastName\" = @0)"));
284290

@@ -288,9 +294,6 @@ public void API_Sqlite_Examples()
288294
db.UpdateOnly(() => new Person { FirstName = "JJ" }, db.From<Person>().Where(p => p.LastName == "Hendrix"));
289295
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@1 WHERE (\"LastName\" = @0)"));
290296

291-
db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, db.From<Person>().Update(p => p.FirstName));
292-
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@0"));
293-
294297
db.UpdateOnly(new Person { FirstName = "JJ" }, db.From<Person>().Update(p => p.FirstName).Where(x => x.FirstName == "Jimi"));
295298
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@1 WHERE (\"FirstName\" = @0)"));
296299

tests/ServiceStack.OrmLite.Tests/Legacy/ApiSqlServerLegacyTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,13 @@ public void API_SqlServer_Legacy_Examples()
8080
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName='WaterHouse' WHERE Id=7"));
8181

8282
db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(x => new { x.FirstName, x.Age }));
83-
Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES ('Amy',27)"));
83+
Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)"));
8484

8585
db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, db.From<PersonWithAutoId>().Insert(x => new { x.FirstName, x.Age }));
86-
Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES ('Amy',27)"));
86+
Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)"));
8787

8888
db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(x => new { x.FirstName, x.Age }));
89-
Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES ('Amy',27)"));
89+
Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)"));
9090

9191
db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, q => q.Update(x => x.FirstName));
9292
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@0"));

tests/ServiceStack.OrmLite.Tests/Legacy/ApiSqliteLegacyTests.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,14 @@ public void API_Sqlite_Legacy_Examples()
7777
var rowsAffected = db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt("WaterHouse", 7));
7878
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName='WaterHouse' WHERE Id=7"));
7979

80-
db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, ev => ev.Insert(p => new { p.FirstName, p.Age }));
81-
Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES ('Amy',27)"));
80+
db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(x => new { x.FirstName, x.Age }));
81+
Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)"));
82+
83+
db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, db.From<PersonWithAutoId>().Insert(x => new { x.FirstName, x.Age }));
84+
Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)"));
85+
86+
db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(x => new { x.FirstName, x.Age }));
87+
Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)"));
8288

8389
db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, ev => ev.Update(p => p.FirstName));
8490
Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@0"));

0 commit comments

Comments
 (0)