Skip to content

Commit

Permalink
Support EF's ExecuteDeleteAsync (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
hbulens authored Jul 9, 2024
1 parent a915b86 commit 134efeb
Show file tree
Hide file tree
Showing 12 changed files with 77 additions and 57 deletions.
8 changes: 4 additions & 4 deletions src/core/Dime.Repositories.Sql/Dime.Repositories.Sql.csproj
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<VersionPrefix>2.0.2.0</VersionPrefix>
<AssemblyVersion>2.0.2.0</AssemblyVersion>
<FileVersion>2.0.2.0</FileVersion>
<VersionPrefix>2.0.3.0</VersionPrefix>
<AssemblyVersion>2.0.3.0</AssemblyVersion>
<FileVersion>2.0.3.0</FileVersion>
<Authors>Dime Software</Authors>
<Version>2.0.2.0</Version>
<Version>2.0.3.0</Version>
<Authors>Dime Software</Authors>
<TargetFrameworks>net8.0</TargetFrameworks>
<AssemblyName>Dime.Repositories.Sql</AssemblyName>
Expand Down
60 changes: 31 additions & 29 deletions src/core/Dime.Repositories.Sql/ISqlRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,60 +5,62 @@
namespace Dime.Repositories
{
/// <summary>
///
/// Defines a SQL repository interface with support for executing SQL commands and stored procedures.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="T">The type of the entity.</typeparam>
public interface ISqlRepository<T> : IRepository<T>, IStoredProcedureRepository where T : class
{
/// <summary>
/// Executes the SQL asynchronous.
/// Executes the provided SQL command asynchronously.
/// </summary>
/// <param name="sql">The SQL.</param>
/// <returns></returns>
/// <param name="sql">The SQL command to execute.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
Task ExecuteSqlAsync(string sql);

/// <summary>
/// Executes the stored procedure asynchronous.
/// Executes the specified stored procedure asynchronously.
/// </summary>
/// <param name="command">The name of the stored procedure.</param>
/// <param name="parameters">The parameters.</param>
/// <returns></returns>
/// <param name="command">The name of the stored procedure to execute.</param>
/// <param name="parameters">The parameters to pass to the stored procedure.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains the number of rows affected.</returns>
Task<int> ExecuteStoredProcedureAsync(string command, params DbParameter[] parameters);

/// <summary>
/// Executes the stored procedure asynchronous.
/// Executes the specified stored procedure asynchronously with a given schema.
/// </summary>
/// <param name="command">The name of the stored procedure.</param>
/// <param name="schema"></param>
/// <param name="parameters">The parameters.</param>
/// <returns></returns>
/// <param name="command">The name of the stored procedure to execute.</param>
/// <param name="schema">The schema of the stored procedure. Defaults to "dbo".</param>
/// <param name="parameters">The parameters to pass to the stored procedure.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains the number of rows affected.</returns>
Task<int> ExecuteStoredProcedureAsync(string command, string schema = "dbo", params DbParameter[] parameters);

/// <summary>
/// Executes the stored procedure asynchronous.
/// Executes the specified stored procedure asynchronously and returns a single result.
/// </summary>
/// <param name="command">The name of the stored procedure.</param>
/// <param name="schema"></param>
/// <param name="parameters">The parameters.</param>
/// <returns></returns>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <param name="command">The name of the stored procedure to execute.</param>
/// <param name="schema">The schema of the stored procedure. Defaults to "dbo".</param>
/// <param name="parameters">The parameters to pass to the stored procedure.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains the result of the stored procedure.</returns>
Task<int> ExecuteStoredProcedureAsync<TResult>(TResult command, string schema = "dbo", params DbParameter[] parameters);

/// <summary>
/// Executes the stored procedure asynchronous.
/// Executes the specified stored procedure asynchronously and returns a collection of results.
/// </summary>
/// <param name="command">The name of the stored procedure.</param>
/// <param name="parameters">The parameters.</param>
/// <returns></returns>
/// <typeparam name="TResult">The type of the results.</typeparam>
/// <param name="command">The name of the stored procedure to execute.</param>
/// <param name="parameters">The parameters to pass to the stored procedure.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains a collection of results.</returns>
Task<IEnumerable<TResult>> ExecuteStoredProcedureAsync<TResult>(string command, params DbParameter[] parameters);

/// <summary>
///
/// Executes the specified stored procedure asynchronously with a given schema and returns a collection of results.
/// </summary>
/// <typeparam name="TResult"></typeparam>
/// <param name="name"></param>
/// <param name="schema"></param>
/// <param name="parameters"></param>
/// <returns></returns>
/// <typeparam name="TResult">The type of the results.</typeparam>
/// <param name="name">The name of the stored procedure to execute.</param>
/// <param name="schema">The schema of the stored procedure. Defaults to "dbo".</param>
/// <param name="parameters">The parameters to pass to the stored procedure.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains a collection of results.</returns>
Task<IEnumerable<TResult>> ExecuteStoredProcedureAsync<TResult>(string name, string schema = "dbo", params DbParameter[] parameters);
}
}
8 changes: 4 additions & 4 deletions src/core/Dime.Repositories/Dime.Repositories.csproj
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<VersionPrefix>2.0.0.0</VersionPrefix>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
<FileVersion>2.0.0.0</FileVersion>
<VersionPrefix>2.0.1.0</VersionPrefix>
<AssemblyVersion>2.0.1.0</AssemblyVersion>
<FileVersion>2.0.1.0</FileVersion>
<Authors>Dime Software</Authors>
<Version>2.0.0.0</Version>
<Version>2.0.1.0</Version>
<TargetFrameworks>net8.0</TargetFrameworks>
<AssemblyName>Dime.Repositories</AssemblyName>
<PackageId>Dime.Repositories</PackageId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ public interface IDeleteRepository<TEntity> : IDisposable where TEntity : class
/// <returns>Void</returns>
Task DeleteAsync(object? id);

/// <summary>
/// Removes all records
/// </summary>
/// <returns>Task</returns>
Task DeleteAsync();

/// <summary>
/// Removes the record from the data store by its identifier
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions src/core/Dime.Repositories/Models/Page.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public Page()
public Page(IEnumerable<T> data)
{
Data = data;
Summary = new List<dynamic>();
Summary = [];
}

public Page(IEnumerable<T> data, int total)
Expand All @@ -32,7 +32,7 @@ public Page(IEnumerable<T> data, int total, string message)
public Page(IEnumerable<T> data, int total, string message, IEnumerable<dynamic> summary)
: this(data, total, message)
{
Summary = summary != null ? summary.ToList() : new List<dynamic>();
Summary = summary != null ? summary.ToList() : [];
}

public IEnumerable<T> Data { get; set; }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup Label="Globals">
<VersionPrefix>2.0.2.0</VersionPrefix>
<AssemblyVersion>2.0.2.0</AssemblyVersion>
<FileVersion>2.0.2.0</FileVersion>
<VersionPrefix>2.0.3.0</VersionPrefix>
<AssemblyVersion>2.0.3.0</AssemblyVersion>
<FileVersion>2.0.3.0</FileVersion>
<LangVersion>latest</LangVersion>
</PropertyGroup>

Expand All @@ -24,7 +24,7 @@
<PackageId>Dime.Repositories.Sql.EntityFramework</PackageId>
<PackageTags>Entity Framework;Repository;SQL</PackageTags>
<PackageIconUrl>https://cdn.dime-software.com/dime-software/logo-shape.png</PackageIconUrl>
<Version>2.0.2.0</Version>
<Version>2.0.3.0</Version>
<Description>Implementation of the repository pattern with Microsoft SQL using Entity Framework Core</Description>
<Copyright>Copyright © 2024</Copyright>
<PackageProjectUrl>https://github.com/dimesoftware/repository</PackageProjectUrl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public virtual async Task<IQueryable<TEntity>> CreateAsync(IQueryable<TEntity> e
if (!entities.Any())
return entities;

List<TEntity> newEntities = new();
List<TEntity> newEntities = [];
TContext ctx = Context;
foreach (TEntity entity in entities.ToList())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ namespace Dime.Repositories
{
public partial class EfRepository<TEntity, TContext>
{
public virtual async Task DeleteAsync()
{
TContext ctx = Context;
await ctx.Set<TEntity>().ExecuteDeleteAsync();
}

public virtual async Task DeleteAsync(object? id)
{
if (id is IEnumerable)
Expand Down Expand Up @@ -91,15 +97,7 @@ public virtual async Task DeleteAsync(TEntity entity, bool commit)
public virtual async Task DeleteAsync(Expression<Func<TEntity, bool>> where)
{
TContext ctx = Context;
IEnumerable<TEntity> entities = ctx.Set<TEntity>().With(where).AsNoTracking().ToList();
if (entities.Any())
{
foreach (TEntity item in entities)
ctx.Set<TEntity>().Attach(item);

ctx.Set<TEntity>().RemoveRange(entities);
await SaveChangesAsync(ctx);
}
await ctx.Set<TEntity>().With(where).ExecuteDeleteAsync();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public virtual IQueryable<TEntity> Create(IQueryable<TEntity> entities)
if (!entities.Any())
return entities;

List<TEntity> newEntities = new();
List<TEntity> newEntities = [];
List<TEntity> entitiesToCreate = entities.ToList();
using TContext ctx = Context;
foreach (TEntity entity in entitiesToCreate)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ internal static class DataReaderExtensions
{
internal static List<T> GetRecords<T>(this IDataReader reader)
{
List<T> result = new();
List<T> result = [];
while (reader.Read())
{
T t = (T)typeof(T).GetConstructor(Type.EmptyTypes).Invoke(Array.Empty<object>());
Expand Down
2 changes: 1 addition & 1 deletion src/providers/EntityFramework/Utilities/EFExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal static IQueryable<TEntity> Include<TEntity>(this IQueryable<TEntity> qu
if (includes == null)
return query;

List<string> includeList = new();
List<string> includeList = [];
if (includes.Length != 0)
return includes
.Where(x => !string.IsNullOrEmpty(x) && !includeList.Contains(x))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,26 @@ public async Task DeleteAsync_ByIds_ShouldRemoveList()
using TestDatabase testDb = new();
using IRepository<Blog> repo = new EfRepository<Blog, BloggingContext>(new BloggingContext(testDb.Options));

List<int> ids = new() { 1, 2 };
List<int> ids = [1, 2];
await repo.DeleteAsync(ids);

// Use a separate instance of the context to verify correct data was saved to database
await using BloggingContext context = new(testDb.Options);
Assert.AreEqual(1, context.Blogs.Count());
}

[TestMethod]
public async Task DeleteAsync_Bulk_ShouldRemoveList()
{
using TestDatabase testDb = new();
using IRepository<Blog> repo = new EfRepository<Blog, BloggingContext>(new BloggingContext(testDb.Options));

List<int> ids = [1, 2];
await repo.DeleteAsync();

// Use a separate instance of the context to verify correct data was saved to database
await using BloggingContext context = new(testDb.Options);
Assert.AreEqual(0, context.Blogs.Count());
}
}
}

0 comments on commit 134efeb

Please sign in to comment.