Skip to content

Commit 516d183

Browse files
author
David Lebee
committed
some batch actions, and added some methods while being there :)
1 parent e7383e7 commit 516d183

File tree

3 files changed

+208
-2
lines changed

3 files changed

+208
-2
lines changed

PoweredSoft.ObjectStorage.Core/IObjectStorageCollection.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,38 @@ public interface IObjectStorageCollection<TEntity>
2020
Task<TEntity> UpdateAsync(TEntity entity, CancellationToken cancellationToken = default(CancellationToken));
2121
IQueryable<TEntity> AsQueryable();
2222
List<PropertyInfo> GetObjectKeys();
23+
Task<bool> AnyAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken));
24+
Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken));
25+
Task<long> LongCountAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken));
26+
Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken));
27+
Task<TEntity> FirstAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken));
28+
29+
Task UpdateManyAsync<TField>(Expression<Func<TEntity, bool>> predicate,
30+
Expression<Func<TEntity, TField>> fieldExpression, TField value,
31+
CancellationToken cancellationToken = default);
32+
33+
Task UpdateManyAsync<TField, TField2>(Expression<Func<TEntity, bool>> predicate,
34+
Expression<Func<TEntity, TField>> fieldExpression, TField value,
35+
Expression<Func<TEntity, TField2>> fieldExpression2, TField2 value2,
36+
CancellationToken cancellationToken = default);
37+
38+
Task UpdateManyAsync<TField, TField2, TField3>(Expression<Func<TEntity, bool>> predicate,
39+
Expression<Func<TEntity, TField>> fieldExpression, TField value,
40+
Expression<Func<TEntity, TField2>> fieldExpression2, TField2 value2,
41+
Expression<Func<TEntity, TField3>> fieldExpression3, TField3 value3,
42+
CancellationToken cancellationToken = default);
43+
44+
Task UpdateOneAsync<TField>(Expression<Func<TEntity, bool>> predicate,
45+
Expression<Func<TEntity, TField>> fieldExpression, TField value,
46+
CancellationToken cancellationToken = default);
47+
Task UpdateOneAsync<TField, TField2>(Expression<Func<TEntity, bool>> predicate,
48+
Expression<Func<TEntity, TField>> fieldExpression, TField value,
49+
Expression<Func<TEntity, TField2>> fieldExpression2, TField2 value2,
50+
CancellationToken cancellationToken = default);
51+
Task UpdateOneAsync<TField, TField2, TField3>(Expression<Func<TEntity, bool>> predicate,
52+
Expression<Func<TEntity, TField>> fieldExpression, TField value,
53+
Expression<Func<TEntity, TField2>> fieldExpression2, TField2 value2,
54+
Expression<Func<TEntity, TField3>> fieldExpression3, TField3 value3,
55+
CancellationToken cancellationToken = default);
2356
}
2457
}

PoweredSoft.ObjectStorage.MongoDB.Tests/CrudTests.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,35 @@ namespace PoweredSoft.ObjectStorage.MongoDB.Tests
99
{
1010
public class CrudTests
1111
{
12+
[Fact]
13+
public async Task UpdateMany()
14+
{
15+
var osc = MongoDatabaseFactory.GetObjectStorageContext();
16+
var collection = osc.GetCollection<Contact>();
17+
var a = await collection.AddAsync(new Contact
18+
{
19+
LastName = "A",
20+
FirstName = "A"
21+
});
22+
23+
var b = await collection.AddAsync(new Contact
24+
{
25+
LastName = "B",
26+
FirstName = "B"
27+
});
28+
29+
await collection.UpdateManyAsync(t => t.LastName == "A" || t.LastName == "B", t => t.LastName, "C");
30+
var howManyCs = await collection.GetAllAsync(t => t.LastName == "C");
31+
var howManyCs2 = await collection.LongCountAsync(t => t.LastName == "C");
32+
Assert.Equal(2, howManyCs.Count);
33+
Assert.Equal(2, howManyCs2);
34+
35+
36+
// clean up.
37+
await collection.DeleteAsync(a);
38+
await collection.DeleteAsync(b);
39+
}
40+
1241
[Fact]
1342
public async Task CreateUpdateThenDelete()
1443
{
@@ -26,6 +55,12 @@ public async Task CreateUpdateThenDelete()
2655
var updatedContact = await collection.UpdateAsync(contact);
2756
Assert.Equal("Norris", updatedContact.LastName);
2857

58+
// update name back to not norris
59+
await collection.UpdateOneAsync(t => t.Id == contact.Id, t => t.LastName, "Not Norris");
60+
61+
var updatedContact2 = await collection.FirstAsync(t => t.Id == contact.Id);
62+
Assert.Equal("Not Norris", updatedContact2.LastName);
63+
2964
// delete the test.
3065
await collection.DeleteAsync(updatedContact);
3166

@@ -49,6 +84,13 @@ public async Task TestGetAsync()
4984
var fetchedUsingGetAsync = await collection.GetAsync(contact.Id);
5085
Assert.NotNull(fetchedUsingGetAsync);
5186

87+
Assert.True(await collection.AnyAsync(t => t.Id == contact.Id), "Any async does not work");
88+
Assert.NotNull(await collection.FirstOrDefaultAsync(t => t.Id == contact.Id));
89+
90+
// does not crash.
91+
await collection.FirstAsync(t => t.Id == contact.Id);
92+
93+
5294
// now delete it.
5395
await collection.DeleteAsync(fetchedUsingGetAsync);
5496
}

PoweredSoft.ObjectStorage.MongoDB/MongoObjectStorageCollection.cs

Lines changed: 133 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
using System.Threading;
77
using System.Threading.Tasks;
88
using MongoDB.Bson.Serialization.Attributes;
9-
using MongoDB.Driver;
9+
using MongoDB.Driver;
10+
using MongoDB.Driver.Linq;
1011
using PoweredSoft.DynamicLinq.Helpers;
1112
using PoweredSoft.ObjectStorage.Core;
1213

@@ -32,6 +33,11 @@ public MongoObjectStorageCollection(IMongoCollection<TEntity> collection)
3233
return entity;
3334
}
3435

36+
public Task<bool> AnyAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken))
37+
{
38+
return MongoQueryable.AnyAsync(Collection.AsQueryable(), predicate, cancellationToken);
39+
}
40+
3541
public IQueryable<TEntity> AsQueryable()
3642
{
3743
return Collection.AsQueryable();
@@ -95,6 +101,131 @@ public List<PropertyInfo> GetObjectKeys()
95101
{
96102
GetBsonIdProperty()
97103
};
98-
}
104+
}
105+
106+
public Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default)
107+
{
108+
return this.Collection.AsQueryable().FirstOrDefaultAsync(predicate, cancellationToken);
109+
}
110+
111+
public Task<TEntity> FirstAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default)
112+
{
113+
return this.Collection.AsQueryable().FirstAsync(predicate, cancellationToken);
114+
}
115+
116+
public async Task UpdateManyAsync<TField>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TField>> fieldExpression, TField value, CancellationToken cancellationToken = default)
117+
{
118+
var updateDefinition = Builders<TEntity>.Update.Set<TField>(fieldExpression, value);
119+
await Collection.UpdateManyAsync(predicate, updateDefinition, new UpdateOptions()
120+
{
121+
IsUpsert = false
122+
}, cancellationToken);
123+
}
124+
125+
public async Task UpdateManyAsync<TField, TField2>(Expression<Func<TEntity, bool>> predicate,
126+
Expression<Func<TEntity, TField>> fieldExpression, TField value,
127+
Expression<Func<TEntity, TField2>> fieldExpression2, TField2 value2,
128+
129+
CancellationToken cancellationToken = default)
130+
{
131+
var updateDefinition = Builders<TEntity>.Update
132+
.Set(fieldExpression, value)
133+
.Set(fieldExpression2, value2)
134+
;
135+
136+
await Collection.UpdateManyAsync(predicate, updateDefinition, new UpdateOptions()
137+
{
138+
IsUpsert = false
139+
}, cancellationToken);
140+
}
141+
142+
public async Task UpdateManyAsync<TField, TField2, TField3>(Expression<Func<TEntity, bool>> predicate,
143+
Expression<Func<TEntity, TField>> fieldExpression, TField value,
144+
Expression<Func<TEntity, TField2>> fieldExpression2, TField2 value2,
145+
Expression<Func<TEntity, TField3>> fieldExpression3, TField3 value3,
146+
CancellationToken cancellationToken = default)
147+
{
148+
var updateDefinition = Builders<TEntity>.Update
149+
.Set(fieldExpression, value)
150+
.Set(fieldExpression2, value2)
151+
.Set(fieldExpression3, value3)
152+
;
153+
154+
await Collection.UpdateManyAsync(predicate, updateDefinition, new UpdateOptions()
155+
{
156+
IsUpsert = false
157+
}, cancellationToken);
158+
}
159+
160+
public async Task UpdateOneAsync<TField>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TField>> fieldExpression, TField value, CancellationToken cancellationToken = default)
161+
{
162+
var updateDefinition = Builders<TEntity>.Update.Set<TField>(fieldExpression, value);
163+
await Collection.UpdateOneAsync(predicate, updateDefinition, new UpdateOptions()
164+
{
165+
IsUpsert = false
166+
}, cancellationToken);
167+
}
168+
169+
public async Task UpdateOneAsync<TField, TField2>(Expression<Func<TEntity, bool>> predicate,
170+
Expression<Func<TEntity, TField>> fieldExpression, TField value,
171+
Expression<Func<TEntity, TField2>> fieldExpression2, TField2 value2,
172+
CancellationToken cancellationToken = default)
173+
{
174+
var updateDefinition = Builders<TEntity>.Update
175+
.Set(fieldExpression, value)
176+
.Set(fieldExpression2, value2);
177+
178+
await Collection.UpdateOneAsync(predicate, updateDefinition, new UpdateOptions()
179+
{
180+
IsUpsert = false
181+
}, cancellationToken);
182+
}
183+
184+
public async Task UpdateOneAsync<TField, TField2, TField3>(Expression<Func<TEntity, bool>> predicate,
185+
Expression<Func<TEntity, TField>> fieldExpression, TField value,
186+
Expression<Func<TEntity, TField2>> fieldExpression2, TField2 value2,
187+
Expression<Func<TEntity, TField3>> fieldExpression3, TField3 value3,
188+
CancellationToken cancellationToken = default)
189+
{
190+
var updateDefinition = Builders<TEntity>.Update
191+
.Set(fieldExpression, value)
192+
.Set(fieldExpression2, value2)
193+
.Set(fieldExpression3, value3)
194+
;
195+
196+
await Collection.UpdateOneAsync(predicate, updateDefinition, new UpdateOptions()
197+
{
198+
IsUpsert = false
199+
}, cancellationToken);
200+
}
201+
202+
public async Task UpdateOneAsync(Expression<Func<TEntity, bool>> predicate, UpdateDefinition<TEntity> updateDefinition, CancellationToken cancellationToken = default)
203+
{
204+
await Collection.UpdateOneAsync(predicate, updateDefinition, new UpdateOptions()
205+
{
206+
IsUpsert = false
207+
}, cancellationToken);
208+
}
209+
210+
public async Task UpdateManyAsync(Expression<Func<TEntity, bool>> predicate, UpdateDefinition<TEntity> updateDefinition, CancellationToken cancellationToken = default)
211+
{
212+
await Collection.UpdateManyAsync(predicate, updateDefinition, new UpdateOptions()
213+
{
214+
IsUpsert = false
215+
}, cancellationToken);
216+
}
217+
218+
public async Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default)
219+
{
220+
var longResult = await Collection.CountDocumentsAsync(predicate, null, cancellationToken);
221+
if (longResult > int.MaxValue)
222+
throw new Exception("Exceeds integer maximum value");
223+
return (int)longResult;
224+
}
225+
226+
public Task<long> LongCountAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default)
227+
{
228+
return Collection.CountDocumentsAsync(predicate, null, cancellationToken);
229+
}
99230
}
100231
}

0 commit comments

Comments
 (0)