Skip to content

Commit

Permalink
feat: support ef7 ExecuteUpdateAsync
Browse files Browse the repository at this point in the history
  • Loading branch information
SonicGD committed Jan 16, 2023
1 parent f1306fd commit fa5c76d
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/Sitko.Core.Repository.EntityFrameworkCore/EFRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.Logging;

Expand All @@ -19,6 +20,13 @@ public interface IEFRepository : IRepository
public interface IEFRepository<TEntity> : IEFRepository where TEntity : class, IEntity
{
Task<int> DeleteAllAsync(Expression<Func<TEntity, bool>> where, CancellationToken cancellationToken = default);

Task<int> UpdateAllAsync(Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setPropertyCalls,
CancellationToken cancellationToken = default);

Task<int> UpdateAllAsync(Expression<Func<TEntity, bool>> where,
Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setPropertyCalls,
CancellationToken cancellationToken = default);
}

public abstract class EFRepository<TEntity, TEntityPk, TDbContext> :
Expand Down Expand Up @@ -51,6 +59,20 @@ public Task<int> DeleteAllRawAsync(string conditions, CancellationToken cancella
context => context.Set<TEntity>().Where(where).ExecuteDeleteAsync(cancellationToken),
cancellationToken);

public Task<int> UpdateAllAsync(
Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setPropertyCalls,
CancellationToken cancellationToken = default) =>
ExecuteDbContextOperationAsync(
context => context.Set<TEntity>().ExecuteUpdateAsync(setPropertyCalls, cancellationToken),
cancellationToken);

public Task<int> UpdateAllAsync(Expression<Func<TEntity, bool>> where,
Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setPropertyCalls,
CancellationToken cancellationToken = default) =>
ExecuteDbContextOperationAsync(
context => context.Set<TEntity>().Where(where).ExecuteUpdateAsync(setPropertyCalls, cancellationToken),
cancellationToken);

public Task<int> DeleteAllAsync(CancellationToken cancellationToken = default) =>
ExecuteDbContextOperationAsync(context => context.Set<TEntity>().ExecuteDeleteAsync(cancellationToken),
cancellationToken);
Expand Down
44 changes: 44 additions & 0 deletions tests/Sitko.Core.Repository.EntityFrameworkCore.Tests/EFTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using Sitko.Core.Repository.EntityFrameworkCore.Tests.Data;
using Sitko.Core.Repository.Tests;
using Sitko.Core.Repository.Tests.Data;
Expand Down Expand Up @@ -103,4 +104,47 @@ public async Task DeleteAllCondition()
item = await repository.GetByIdAsync(item.Id);
item.Should().BeNull();
}

[Fact]
public async Task UpdateAllCondition()
{
var scope = await GetScopeAsync();

var repository = scope.GetService<IRepository<FooModel, Guid>>();
Assert.NotNull(repository);
var item = await repository.GetAsync();
Assert.NotNull(item);
var oldValue = item.FooText;
var newText = Guid.NewGuid().ToString();
oldValue.Should().NotBe(newText);

var efRepository = repository as IEFRepository<FooModel>;
efRepository.Should().NotBeNull();
var updated = await efRepository!.UpdateAllAsync(model => model.Id == item.Id,
calls => calls.SetProperty(model => model.FooText, newText));
updated.Should().Be(1);
item = await repository.RefreshAsync(item);
item.FooText.Should().Be(newText);
}

[Fact]
public async Task UpdateAll()
{
var scope = await GetScopeAsync();

var repository = scope.GetService<IRepository<FooModel, Guid>>();
var newText = Guid.NewGuid().ToString();
Assert.NotNull(repository);
var items = await repository.GetAllAsync();
items.items.Should().NotBeEmpty();
items.items.Should().AllSatisfy(model => model.FooText.Should().NotBe(newText));

var efRepository = repository as IEFRepository<FooModel>;
efRepository.Should().NotBeNull();
var updated = await efRepository!.UpdateAllAsync(calls => calls.SetProperty(model => model.FooText, newText));
updated.Should().Be(items.items.Length);
items = await scope.CreateScope().ServiceProvider.GetRequiredService<IRepository<FooModel, Guid>>()
.GetAllAsync();
items.items.Should().AllSatisfy(model => model.FooText.Should().Be(newText));
}
}

0 comments on commit fa5c76d

Please sign in to comment.