diff --git a/.cr/personal/FavoritesList/List.xml b/.cr/personal/FavoritesList/List.xml
new file mode 100644
index 0000000..a60e5ed
--- /dev/null
+++ b/.cr/personal/FavoritesList/List.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml
index 6a3747f..7ec8fd2 100644
--- a/.github/workflows/dotnetcore.yml
+++ b/.github/workflows/dotnetcore.yml
@@ -21,3 +21,4 @@ jobs:
run: dotnet restore
- name: Build
run: dotnet build --configuration Release
+
diff --git a/README.md b/README.md
index 8a86642..45015fb 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,5 @@
+[](https://wakatime.com/badge/github/AIKICo/UnitOfWork)
# UnitOfWork
A plugin for Microsoft.EntityFrameworkCore to support repository, unit of work patterns, and multiple database with distributed transaction supported.
diff --git a/UnitOfWork.sln b/UnitOfWork.sln
index 15b7ef1..9781ae6 100644
--- a/UnitOfWork.sln
+++ b/UnitOfWork.sln
@@ -16,10 +16,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{9661
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitOfWork", "src\UnitOfWork\UnitOfWork.csproj", "{FD8010C2-982B-470E-A9A5-C0DFA2D14809}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitOfWork.Tests", "test\UnitOfWork.Tests\UnitOfWork.Tests.csproj", "{FDAA4086-21E8-4939-8539-0A1723EC4922}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitOfWork.Host", "samples\UnitOfWork.Host\UnitOfWork.Host.csproj", "{207188FE-2344-4DC1-8656-E02CEF741422}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -30,22 +26,12 @@ Global
{FD8010C2-982B-470E-A9A5-C0DFA2D14809}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FD8010C2-982B-470E-A9A5-C0DFA2D14809}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FD8010C2-982B-470E-A9A5-C0DFA2D14809}.Release|Any CPU.Build.0 = Release|Any CPU
- {FDAA4086-21E8-4939-8539-0A1723EC4922}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {FDAA4086-21E8-4939-8539-0A1723EC4922}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {FDAA4086-21E8-4939-8539-0A1723EC4922}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {FDAA4086-21E8-4939-8539-0A1723EC4922}.Release|Any CPU.Build.0 = Release|Any CPU
- {207188FE-2344-4DC1-8656-E02CEF741422}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {207188FE-2344-4DC1-8656-E02CEF741422}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {207188FE-2344-4DC1-8656-E02CEF741422}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {207188FE-2344-4DC1-8656-E02CEF741422}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{FD8010C2-982B-470E-A9A5-C0DFA2D14809} = {14F86AF9-D2C9-468D-8C71-9BC4785F68A0}
- {FDAA4086-21E8-4939-8539-0A1723EC4922} = {D3C7F3F5-4AB2-4868-8D2C-516DFCFDC349}
- {207188FE-2344-4DC1-8656-E02CEF741422} = {9661083F-4BCD-42D4-9EF8-1187DD9EDA60}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A7B21B30-8D65-449B-B192-64726743EFC3}
diff --git a/samples/UnitOfWork.Host/Controllers/ValuesController.cs b/samples/UnitOfWork.Host/Controllers/ValuesController.cs
index 5fcfe36..5ddff48 100644
--- a/samples/UnitOfWork.Host/Controllers/ValuesController.cs
+++ b/samples/UnitOfWork.Host/Controllers/ValuesController.cs
@@ -6,6 +6,7 @@
using Arch.EntityFrameworkCore.UnitOfWork.Host.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
+using UnitOfWork.Host.Models;
namespace Arch.EntityFrameworkCore.UnitOfWork.Host.Controllers
{
diff --git a/samples/UnitOfWork.Host/Models/BlogggingContext.cs b/samples/UnitOfWork.Host/Models/BlogggingContext.cs
index 1099928..caa208c 100644
--- a/samples/UnitOfWork.Host/Models/BlogggingContext.cs
+++ b/samples/UnitOfWork.Host/Models/BlogggingContext.cs
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
-namespace Arch.EntityFrameworkCore.UnitOfWork.Host.Models
+namespace UnitOfWork.Host.Models
{
public class BloggingContext : DbContext
{
@@ -12,10 +12,7 @@ public BloggingContext(DbContextOptions options)
public DbSet Blogs { get; set; }
public DbSet Posts { get; set; }
- protected override void OnModelCreating(ModelBuilder modelBuilder)
- {
- modelBuilder.EnableAutoHistory(null);
- }
+ protected override void OnModelCreating(ModelBuilder modelBuilder) => modelBuilder.EnableAutoHistory(null);
}
public class Blog
diff --git a/samples/UnitOfWork.Host/Models/CustomBlogRepository.cs b/samples/UnitOfWork.Host/Models/CustomBlogRepository.cs
index c706628..6b171e6 100644
--- a/samples/UnitOfWork.Host/Models/CustomBlogRepository.cs
+++ b/samples/UnitOfWork.Host/Models/CustomBlogRepository.cs
@@ -1,4 +1,6 @@
-namespace Arch.EntityFrameworkCore.UnitOfWork.Host.Models
+using UnitOfWork.Host.Models;
+
+namespace Arch.EntityFrameworkCore.UnitOfWork.Host.Models
{
public class CustomBlogRepository : Repository, IRepository
{
diff --git a/samples/UnitOfWork.Host/Startup.cs b/samples/UnitOfWork.Host/Startup.cs
index b706c5d..661ce9c 100644
--- a/samples/UnitOfWork.Host/Startup.cs
+++ b/samples/UnitOfWork.Host/Startup.cs
@@ -6,6 +6,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Hosting;
+using UnitOfWork.Host.Models;
namespace Arch.EntityFrameworkCore.UnitOfWork.Host
{
diff --git a/samples/UnitOfWork.Host/UnitOfWork.Host.csproj b/samples/UnitOfWork.Host/UnitOfWork.Host.csproj
index 3d001d5..b2605a6 100644
--- a/samples/UnitOfWork.Host/UnitOfWork.Host.csproj
+++ b/samples/UnitOfWork.Host/UnitOfWork.Host.csproj
@@ -3,12 +3,14 @@
netcoreapp3.1
true
Exe
+ false
+
diff --git a/src/UnitOfWork/IRepository.cs b/src/UnitOfWork/IRepository.cs
index a31fef2..fe93c07 100644
--- a/src/UnitOfWork/IRepository.cs
+++ b/src/UnitOfWork/IRepository.cs
@@ -52,6 +52,40 @@ IPagedList GetPagedList(Expression> predicate = nul
bool disableTracking = true,
bool ignoreQueryFilters = false);
+ ///
+ /// Gets all entities. This method is not recommended
+ ///
+ /// The selector for projection.
+ /// A function to test each element for a condition.
+ /// A function to order elements.
+ /// A function to include navigation properties
+ /// true to disable changing tracking; otherwise, false. Default to true.
+ /// Ignore query filters
+ /// An that contains elements that satisfy the condition specified by .
+ /// Ex: This method defaults to a read-only, no-tracking query.
+ IQueryable GetAll(Expression> selector,
+ Expression> predicate = null,
+ Func, IOrderedQueryable> orderBy = null,
+ Func, IIncludableQueryable> include = null, bool disableTracking = true, bool ignoreQueryFilters = false);
+
+ ///
+ /// Gets all entities. This method is not recommended
+ ///
+ /// The selector for projection.
+ /// A function to test each element for a condition.
+ /// A function to order elements.
+ /// A function to include navigation properties
+ /// true to disable changing tracking; otherwise, false. Default to true.
+ /// Ignore query filters
+ /// An that contains elements that satisfy the condition specified by .
+ /// Ex: This method defaults to a read-only, no-tracking query.
+ Task> GetAllAsync(Expression> selector,
+ Expression> predicate = null,
+ Func, IOrderedQueryable> orderBy = null,
+ Func, IIncludableQueryable> include = null,
+ bool disableTracking = true,
+ bool ignoreQueryFilters = false);
+
///
/// Gets the based on a predicate, orderby delegate and page information. This method default no-tracking query.
///
@@ -244,24 +278,6 @@ IQueryable GetAll(Expression> predicate = null,
bool disableTracking = true,
bool ignoreQueryFilters = false);
- ///
- /// Gets all entities. This method is not recommended
- ///
- /// The selector for projection.
- /// A function to test each element for a condition.
- /// A function to order elements.
- /// A function to include navigation properties
- /// true to disable changing tracking; otherwise, false. Default to true.
- /// Ignore query filters
- /// An that contains elements that satisfy the condition specified by .
- /// Ex: This method defaults to a read-only, no-tracking query.
- IQueryable GetAll(Expression> selector,
- Expression> predicate = null,
- Func, IOrderedQueryable> orderBy = null,
- Func, IIncludableQueryable> include = null,
- bool disableTracking = true,
- bool ignoreQueryFilters = false);
-
///
/// Gets all entities. This method is not recommended
///
@@ -284,128 +300,124 @@ Task> GetAllAsync(Expression> predicate = nul
bool disableTracking = true,
bool ignoreQueryFilters = false);
- ///
- /// Gets all entities. This method is not recommended
- ///
- /// The selector for projection.
- /// A function to test each element for a condition.
- /// A function to order elements.
- /// A function to include navigation properties
- /// true to disable changing tracking; otherwise, false. Default to true.
- /// Ignore query filters
- /// An that contains elements that satisfy the condition specified by .
- /// Ex: This method defaults to a read-only, no-tracking query.
- Task> GetAllAsync(Expression> selector,
- Expression> predicate = null,
- Func, IOrderedQueryable> orderBy = null,
- Func, IIncludableQueryable> include = null,
- bool disableTracking = true,
- bool ignoreQueryFilters = false);
-
///
/// Gets the count based on a predicate.
///
///
+ ///
///
- int Count(Expression> predicate = null);
+ int Count(Expression> predicate = null, bool ignoreQueryFilters = false);
///
/// Gets async the count based on a predicate.
///
///
+ ///
///
- Task CountAsync(Expression> predicate = null);
+ Task CountAsync(Expression> predicate = null, bool ignoreQueryFilters = false);
///
/// Gets the long count based on a predicate.
///
///
+ ///
///
- long LongCount(Expression> predicate = null);
+ long LongCount(Expression> predicate = null, bool ignoreQueryFilters = false);
///
/// Gets async the long count based on a predicate.
///
///
+ ///
///
- Task LongCountAsync(Expression> predicate = null);
+ Task LongCountAsync(Expression> predicate = null, bool ignoreQueryFilters = false);
///
/// Gets the max based on a predicate.
///
///
/// ///
+ ///
/// decimal
- T Max(Expression> predicate = null, Expression> selector = null);
+ T Max(Expression> predicate = null, Expression> selector = null, bool ignoreQueryFilters = false);
///
/// Gets the async max based on a predicate.
///
///
/// ///
+ ///
/// decimal
- Task MaxAsync(Expression> predicate = null, Expression> selector = null);
+ Task MaxAsync(Expression> predicate = null, Expression> selector = null, bool ignoreQueryFilters = false);
///
/// Gets the min based on a predicate.
///
///
///
+ ///
/// decimal
- T Min(Expression> predicate = null, Expression> selector = null);
+ T Min(Expression> predicate = null, Expression> selector = null, bool ignoreQueryFilters = false);
///
/// Gets the async min based on a predicate.
///
///
///
+ ///
/// decimal
- Task MinAsync(Expression> predicate = null, Expression> selector = null);
+ Task MinAsync(Expression> predicate = null, Expression> selector = null, bool ignoreQueryFilters = false);
///
/// Gets the average based on a predicate.
///
///
/// ///
+ ///
/// decimal
- decimal Average (Expression> predicate = null, Expression> selector = null);
+ decimal Average (Expression> predicate = null, Expression> selector = null, bool ignoreQueryFilters = false);
///
- /// Gets the async average based on a predicate.
- ///
- ///
- /// ///
- /// decimal
- Task AverageAsync(Expression> predicate = null, Expression> selector = null);
+ /// Gets the async average based on a predicate.
+ ///
+ ///
+ /// ///
+ ///
+ /// decimal
+ Task AverageAsync(Expression> predicate = null, Expression> selector = null, bool ignoreQueryFilters = false);
///
/// Gets the sum based on a predicate.
///
///
/// ///
+ ///
/// decimal
- decimal Sum (Expression> predicate = null, Expression> selector = null);
+ decimal Sum (Expression> predicate = null, Expression> selector = null, bool ignoreQueryFilters = false);
///
/// Gets the async sum based on a predicate.
///
///
/// ///
+ ///
/// decimal
- Task SumAsync (Expression> predicate = null, Expression> selector = null);
+ Task SumAsync (Expression> predicate = null, Expression> selector = null, bool ignoreQueryFilters = false);
///
/// Gets the Exists record based on a predicate.
///
///
+ ///
///
- bool Exists(Expression> selector = null);
+ bool Exists(Expression> selector = null, bool ignoreQueryFilters = false);
///
/// Gets the Async Exists record based on a predicate.
///
///
+ ///
///
- Task ExistsAsync(Expression> selector = null);
+ Task ExistsAsync(Expression> selector = null, bool ignoreQueryFilters = false);
///
/// Inserts a new entity synchronously.
@@ -490,6 +502,28 @@ Task> GetAllAsync(Expression> sel
/// The entities.
void Delete(IEnumerable entities);
+ ///
+ /// Bulk Delete the specified entity.
+ ///
+ void BulkDelete();
+
+ ///
+ /// ASync Bulk Delete the specified entity.
+ ///
+ Task BulkDeleteAsync();
+
+ ///
+ /// Bulk Update the specified entity.
+ /// the entity property
+ ///
+ void BulkUpdate(Expression, SetPropertyCalls>> setPropertyCalls);
+
+ ///
+ /// Async Bulk Update the specified entity.
+ /// the entity property
+ ///
+ Task BulkUpdateAsync(Expression, SetPropertyCalls>> setPropertyCalls);
+
///
/// Change entity state for patch method on web api.
///
diff --git a/src/UnitOfWork/Repository.cs b/src/UnitOfWork/Repository.cs
index c3fff96..005946c 100644
--- a/src/UnitOfWork/Repository.cs
+++ b/src/UnitOfWork/Repository.cs
@@ -12,6 +12,7 @@
using Microsoft.EntityFrameworkCore.Query;
using Arch.EntityFrameworkCore.UnitOfWork.Collections;
using Microsoft.EntityFrameworkCore.ChangeTracking;
+// ReSharper disable All
namespace Arch.EntityFrameworkCore.UnitOfWork
{
@@ -53,10 +54,7 @@ public virtual void ChangeTable(string table)
/// Gets all entities. This method is not recommended
///
/// The .
- public IQueryable GetAll()
- {
- return _dbSet;
- }
+ public IQueryable GetAll() => _dbSet;
///
/// Gets all entities. This method is not recommended
@@ -116,7 +114,7 @@ public IQueryable GetAll(
/// Ignore query filters
/// An that contains elements that satisfy the condition specified by .
/// Ex: This method defaults to a read-only, no-tracking query.
- public IQueryable GetAll(Expression> selector,
+ public IQueryable GetAll(Expression> selector,
Expression> predicate = null,
Func, IOrderedQueryable> orderBy = null,
Func, IIncludableQueryable> include = null, bool disableTracking = true, bool ignoreQueryFilters = false)
@@ -153,6 +151,56 @@ public IQueryable GetAll(Expression> sel
}
}
+ ///
+ /// Gets all entities. This method is not recommended
+ ///
+ /// The selector for projection.
+ /// A function to test each element for a condition.
+ /// A function to order elements.
+ /// A function to include navigation properties
+ /// true to disable changing tracking; otherwise, false. Default to true.
+ /// Ignore query filters
+ /// An that contains elements that satisfy the condition specified by .
+ /// Ex: This method defaults to a read-only, no-tracking query.
+ public async Task> GetAllAsync(Expression> selector,
+ Expression> predicate = null,
+ Func, IOrderedQueryable> orderBy = null,
+ Func, IIncludableQueryable> include = null,
+ bool disableTracking = true, bool ignoreQueryFilters = false)
+ {
+ IQueryable query = _dbSet;
+
+ if (disableTracking)
+ {
+ query = query.AsNoTracking();
+ }
+
+ if (include != null)
+ {
+ query = include(query);
+ }
+
+ if (predicate != null)
+ {
+ query = query.Where(predicate);
+ }
+
+ if (ignoreQueryFilters)
+ {
+ query = query.IgnoreQueryFilters();
+ }
+
+
+ if (orderBy != null)
+ {
+ return await orderBy(query).Select(selector).ToListAsync();
+ }
+ else
+ {
+ return await query.Select(selector).ToListAsync();
+ }
+ }
+
///
/// Gets the based on a predicate, orderby delegate and page information. This method default no-tracking query.
///
@@ -586,16 +634,20 @@ public virtual async Task GetFirstOrDefaultAsync(Expression
///
+ ///
///
- public virtual int Count(Expression> predicate = null)
+ public virtual int Count(Expression> predicate = null, bool ignoreQueryFilters = false)
{
+ IQueryable query = _dbSet;
+ if (ignoreQueryFilters) query = query.IgnoreQueryFilters();
+
if (predicate == null)
{
- return _dbSet.Count();
+ return query.Count();
}
else
{
- return _dbSet.Count(predicate);
+ return query.Count(predicate);
}
}
@@ -603,16 +655,20 @@ public virtual int Count(Expression> predicate = null)
/// Gets async the count based on a predicate.
///
///
+ ///
///
- public virtual async Task CountAsync(Expression> predicate = null)
+ public virtual async Task CountAsync(Expression> predicate = null, bool ignoreQueryFilters = false)
{
+ IQueryable query = _dbSet;
+ if (ignoreQueryFilters) query = query.IgnoreQueryFilters();
+
if (predicate == null)
{
- return await _dbSet.CountAsync();
+ return await query.CountAsync();
}
else
{
- return await _dbSet.CountAsync(predicate);
+ return await query.CountAsync(predicate);
}
}
@@ -620,16 +676,20 @@ public virtual async Task CountAsync(Expression> predic
/// Gets the long count based on a predicate.
///
///
+ ///
///
- public virtual long LongCount(Expression> predicate = null)
+ public virtual long LongCount(Expression> predicate = null, bool ignoreQueryFilters = false)
{
+ IQueryable query = _dbSet;
+ if (ignoreQueryFilters) query = query.IgnoreQueryFilters();
+
if (predicate == null)
{
- return _dbSet.LongCount();
+ return query.LongCount();
}
else
{
- return _dbSet.LongCount(predicate);
+ return query.LongCount(predicate);
}
}
@@ -637,16 +697,20 @@ public virtual long LongCount(Expression> predicate = null)
/// Gets async the long count based on a predicate.
///
///
+ ///
///
- public virtual async Task LongCountAsync(Expression> predicate = null)
+ public virtual async Task LongCountAsync(Expression> predicate = null, bool ignoreQueryFilters = false)
{
+ IQueryable query = _dbSet;
+ if (ignoreQueryFilters) query = query.IgnoreQueryFilters();
+
if (predicate == null)
{
- return await _dbSet.LongCountAsync();
+ return await query.LongCountAsync();
}
else
{
- return await _dbSet.LongCountAsync(predicate);
+ return await query.LongCountAsync(predicate);
}
}
@@ -655,13 +719,19 @@ public virtual async Task LongCountAsync(Expression> p
///
///
/// ///
+ ///
/// decimal
- public virtual T Max(Expression> predicate = null, Expression> selector = null)
+ public virtual T Max(
+ Expression> predicate = null,
+ Expression> selector = null, bool ignoreQueryFilters = false)
{
+ IQueryable query = _dbSet;
+ if (ignoreQueryFilters) query = query.IgnoreQueryFilters();
+
if (predicate == null)
- return _dbSet.Max(selector);
+ return query.Max(selector ?? throw new ArgumentNullException(nameof(selector)));
else
- return _dbSet.Where(predicate).Max(selector);
+ return query.Where(predicate).Max(selector ?? throw new ArgumentNullException(nameof(selector)));
}
///
@@ -669,13 +739,17 @@ public virtual T Max(Expression> predicate = null, Expres
///
///
/// ///
+ ///
/// decimal
- public virtual async Task MaxAsync(Expression> predicate = null, Expression> selector = null)
+ public virtual async Task MaxAsync(Expression> predicate = null, Expression> selector = null, bool ignoreQueryFilters = false)
{
+ IQueryable query = _dbSet;
+ if (ignoreQueryFilters) query = query.IgnoreQueryFilters();
+
if (predicate == null)
- return await _dbSet.MaxAsync(selector);
+ return await query.MaxAsync(selector ?? throw new ArgumentNullException(nameof(selector)));
else
- return await _dbSet.Where(predicate).MaxAsync(selector);
+ return await query.Where(predicate).MaxAsync(selector ?? throw new ArgumentNullException(nameof(selector)));
}
///
@@ -683,13 +757,17 @@ public virtual async Task MaxAsync(Expression> predica
///
///
/// ///
+ ///
/// decimal
- public virtual T Min(Expression> predicate = null, Expression> selector = null)
+ public virtual T Min(Expression> predicate = null, Expression> selector = null, bool ignoreQueryFilters = false)
{
+ IQueryable query = _dbSet;
+ if (ignoreQueryFilters) query = query.IgnoreQueryFilters();
+
if (predicate == null)
- return _dbSet.Min(selector);
+ return query.Min(selector ?? throw new ArgumentNullException(nameof(selector)));
else
- return _dbSet.Where(predicate).Min(selector);
+ return query.Where(predicate).Min(selector ?? throw new ArgumentNullException(nameof(selector)));
}
///
@@ -697,13 +775,17 @@ public virtual T Min(Expression> predicate = null, Expres
///
///
/// ///
+ ///
/// decimal
- public virtual async Task MinAsync(Expression> predicate = null, Expression> selector = null)
+ public virtual async Task MinAsync(Expression> predicate = null, Expression> selector = null, bool ignoreQueryFilters = false)
{
+ IQueryable query = _dbSet;
+ if (ignoreQueryFilters) query = query.IgnoreQueryFilters();
+
if (predicate == null)
- return await _dbSet.MinAsync(selector);
+ return await query.MinAsync(selector ?? throw new ArgumentNullException(nameof(selector)));
else
- return await _dbSet.Where(predicate).MinAsync(selector);
+ return await query.Where(predicate).MinAsync(selector ?? throw new ArgumentNullException(nameof(selector)));
}
///
@@ -711,13 +793,17 @@ public virtual async Task MinAsync(Expression> predica
///
///
/// ///
+ ///
/// decimal
- public virtual decimal Average(Expression> predicate = null, Expression> selector = null)
+ public virtual decimal Average(Expression> predicate = null, Expression> selector = null, bool ignoreQueryFilters = false)
{
+ IQueryable query = _dbSet;
+ if (ignoreQueryFilters) query = query.IgnoreQueryFilters();
+
if (predicate == null)
- return _dbSet.Average(selector);
+ return query.Average(selector ?? throw new ArgumentNullException(nameof(selector)));
else
- return _dbSet.Where(predicate).Average(selector);
+ return query.Where(predicate).Average(selector ?? throw new ArgumentNullException(nameof(selector)));
}
///
@@ -725,13 +811,17 @@ public virtual decimal Average(Expression> predicate = null,
///
///
/// ///
+ ///
/// decimal
- public virtual async Task AverageAsync(Expression> predicate = null, Expression> selector = null)
+ public virtual async Task AverageAsync(Expression> predicate = null, Expression> selector = null, bool ignoreQueryFilters = false)
{
+ IQueryable query = _dbSet;
+ if (ignoreQueryFilters) query = query.IgnoreQueryFilters();
+
if (predicate == null)
- return await _dbSet.AverageAsync(selector);
+ return await query.AverageAsync(selector ?? throw new ArgumentNullException(nameof(selector)));
else
- return await _dbSet.Where(predicate).AverageAsync(selector);
+ return await query.Where(predicate).AverageAsync(selector ?? throw new ArgumentNullException(nameof(selector)));
}
///
@@ -739,13 +829,18 @@ public virtual async Task AverageAsync(Expression>
///
///
/// ///
+ ///
/// decimal
- public virtual decimal Sum(Expression> predicate = null, Expression> selector = null)
+ public virtual decimal Sum(Expression> predicate = null,
+ Expression> selector = null, bool ignoreQueryFilters = false)
{
+ IQueryable query = _dbSet;
+ if (ignoreQueryFilters) query = query.IgnoreQueryFilters();
+
if (predicate == null)
- return _dbSet.Sum(selector);
+ return query.Sum(selector ?? throw new ArgumentNullException(nameof(selector)));
else
- return _dbSet.Where(predicate).Sum(selector);
+ return query.Where(predicate).Sum(selector ?? throw new ArgumentNullException(nameof(selector)));
}
///
@@ -753,55 +848,51 @@ public virtual decimal Sum(Expression> predicate = null, Exp
///
///
/// ///
+ ///
/// decimal
- public virtual async Task SumAsync(Expression> predicate = null, Expression> selector = null)
+ public virtual async Task SumAsync(
+ Expression> predicate = null,
+ Expression> selector = null, bool ignoreQueryFilters = false)
{
+ IQueryable query = _dbSet;
+ if (ignoreQueryFilters) query = query.IgnoreQueryFilters();
+
if (predicate == null)
- return await _dbSet.SumAsync(selector);
+ return await query.SumAsync(selector ?? throw new ArgumentNullException(nameof(selector)));
else
- return await _dbSet.Where(predicate).SumAsync(selector);
+ return await query.Where(predicate).SumAsync(selector ?? throw new ArgumentNullException(nameof(selector)));
}
///
/// Gets the exists based on a predicate.
///
///
+ ///
///
- public bool Exists(Expression> selector = null)
+ public bool Exists(Expression> selector = null, bool ignoreQueryFilters = false)
{
- if (selector == null)
- {
- return _dbSet.Any();
- }
- else
- {
- return _dbSet.Any(selector);
- }
+ IQueryable query = _dbSet;
+ if (ignoreQueryFilters) query = query.IgnoreQueryFilters();
+ return selector == null ? query.Any() : query.Any(selector);
}
///
/// Gets the async exists based on a predicate.
///
///
+ ///
///
- public async Task ExistsAsync(Expression> selector = null)
+ public async Task ExistsAsync(Expression> selector = null, bool ignoreQueryFilters = false)
{
- if (selector == null)
- {
- return await _dbSet.AnyAsync();
- }
- else
- {
- return await _dbSet.AnyAsync(selector);
- }
- }
+ IQueryable query = _dbSet;
+ if (ignoreQueryFilters) query = query.IgnoreQueryFilters();
+ return selector == null ? await query.AnyAsync() : await query.AnyAsync(selector);
+ }
+
///
/// Inserts a new entity synchronously.
///
/// The entity to insert.
- public virtual TEntity Insert(TEntity entity)
- {
- return _dbSet.Add(entity).Entity;
- }
+ public virtual TEntity Insert(TEntity entity) => _dbSet.Add(entity).Entity;
///
/// Inserts a range of entities synchronously.
@@ -821,17 +912,13 @@ public virtual TEntity Insert(TEntity entity)
/// The entity to insert.
/// A to observe while waiting for the task to complete.
/// A that represents the asynchronous insert operation.
- public virtual ValueTask> InsertAsync(TEntity entity, CancellationToken cancellationToken = default(CancellationToken))
- {
- return _dbSet.AddAsync(entity, cancellationToken);
-
- // Shadow properties?
- //var property = _dbContext.Entry(entity).Property("Created");
- //if (property != null) {
- //property.CurrentValue = DateTime.Now;
- //}
- }
+ public virtual ValueTask> InsertAsync(TEntity entity, CancellationToken cancellationToken = default(CancellationToken)) => _dbSet.AddAsync(entity, cancellationToken);
+ // Shadow properties?
+ //var property = _dbContext.Entry(entity).Property("Created");
+ //if (property != null) {
+ //property.CurrentValue = DateTime.Now;
+ //}
///
/// Inserts a range of entities asynchronously.
///
@@ -851,20 +938,13 @@ public virtual TEntity Insert(TEntity entity)
/// Updates the specified entity.
///
/// The entity.
- public virtual void Update(TEntity entity)
- {
- _dbSet.Update(entity);
- }
+ public virtual void Update(TEntity entity) => _dbSet.Update(entity);
///
/// Updates the specified entity.
///
/// The entity.
- public virtual void UpdateAsync(TEntity entity)
- {
- _dbSet.Update(entity);
-
- }
+ public virtual void UpdateAsync(TEntity entity) => _dbSet.Update(entity);
///
/// Updates the specified entities.
@@ -893,7 +973,7 @@ public virtual void Delete(object id)
// using a stub entity to mark for deletion
var typeInfo = typeof(TEntity).GetTypeInfo();
var key = _dbContext.Model.FindEntityType(typeInfo).FindPrimaryKey().Properties.FirstOrDefault();
- var property = typeInfo.GetProperty(key?.Name);
+ var property = typeInfo.GetProperty(key?.Name ?? string.Empty);
if (property != null)
{
var entity = Activator.CreateInstance();
@@ -926,10 +1006,7 @@ public virtual void Delete(object id)
/// Gets all entities. This method is not recommended
///
/// The .
- public async Task> GetAllAsync()
- {
- return await _dbSet.ToListAsync();
- }
+ public async Task> GetAllAsync() => await _dbSet.ToListAsync();
///
/// Gets all entities. This method is not recommended
@@ -979,63 +1056,33 @@ public async Task> GetAllAsync(Expression> pr
}
///
- /// Gets all entities. This method is not recommended
+ /// Bulk Delete the specified entity.
///
- /// The selector for projection.
- /// A function to test each element for a condition.
- /// A function to order elements.
- /// A function to include navigation properties
- /// true to disable changing tracking; otherwise, false. Default to true.
- /// Ignore query filters
- /// An that contains elements that satisfy the condition specified by .
- /// Ex: This method defaults to a read-only, no-tracking query.
- public async Task> GetAllAsync(Expression> selector,
- Expression> predicate = null,
- Func, IOrderedQueryable> orderBy = null,
- Func, IIncludableQueryable> include = null,
- bool disableTracking = true, bool ignoreQueryFilters = false)
- {
- IQueryable query = _dbSet;
-
- if (disableTracking)
- {
- query = query.AsNoTracking();
- }
+ public void BulkDelete()=> _dbSet.ExecuteDelete();
- if (include != null)
- {
- query = include(query);
- }
+ ///
+ /// Bulk Delete the specified entity.
+ ///
+ public async Task BulkDeleteAsync() => await _dbSet.ExecuteDeleteAsync();
- if (predicate != null)
- {
- query = query.Where(predicate);
- }
- if (ignoreQueryFilters)
- {
- query = query.IgnoreQueryFilters();
- }
+ ///
+ /// Bulk Update the specified entity.
+ ///
+ /// the entity property
+ public void BulkUpdate(Expression, SetPropertyCalls>> setPropertyCalls) => _dbSet.ExecuteUpdate(setPropertyCalls);
-
- if (orderBy != null)
- {
- return await orderBy(query).Select(selector).ToListAsync();
- }
- else
- {
- return await query.Select(selector).ToListAsync();
- }
- }
+ ///
+ /// Async Bulk Update the specified entity.
+ /// the entity property
+ ///
+ public async Task BulkUpdateAsync(Expression, SetPropertyCalls>> setPropertyCalls) => await _dbSet.ExecuteUpdateAsync(setPropertyCalls);
///
/// Change entity state for patch method on web api.
///
/// The entity.
/// /// The entity state.
- public void ChangeEntityState(TEntity entity, EntityState state)
- {
- _dbContext.Entry(entity).State = state;
- }
+ public void ChangeEntityState(TEntity entity, EntityState state) => _dbContext.Entry(entity).State = state;
}
}
diff --git a/src/UnitOfWork/UnitOfWork.csproj b/src/UnitOfWork/UnitOfWork.csproj
index fdf335f..1494a93 100644
--- a/src/UnitOfWork/UnitOfWork.csproj
+++ b/src/UnitOfWork/UnitOfWork.csproj
@@ -1,25 +1,29 @@
A plugin for Microsoft.EntityFrameworkCore to support repository, unit of work patterns, and multiple database with distributed transaction supported.
- 3.1.0
- rigofunc;rigofunc@outlook.com;
- netstandard2.0
+ 7.1.0
+ rigofunc;rigofunc@outlook.com;qermezkon@gmail.com
+ net7.0
$(NoWarn);CS1591
true
true
Microsoft.EntityFrameworkCore.UnitOfWork
Microsoft.EntityFrameworkCore.UnitOfWork
Entity Framework Core;entity-framework-core;EF;Data;O/RM;unitofwork;Unit Of Work;unit-of-work
- https://github.com/arch/UnitOfWork
+ https://github.com/AikiCo/UnitOfWork
MIT
git
- https://github.com/arch/UnitOfWork.git
- 3.1.16
+ https://github.com/AikiCo/UnitOfWork
+ 7.1.0
true
snupkg
+ 8
+ 7.1.0
+ true
+ cba3a20d-f192-445e-9058-fdbacec3fea3
-
-
+
+
diff --git a/test/UnitOfWork.Tests/InMemoryContext.cs b/test/UnitOfWork.Tests/InMemoryContext.cs
index cf60438..bf693dc 100644
--- a/test/UnitOfWork.Tests/InMemoryContext.cs
+++ b/test/UnitOfWork.Tests/InMemoryContext.cs
@@ -8,9 +8,6 @@ public class InMemoryContext : DbContext
public DbSet Countries { get; set; }
public DbSet Customers { get; set; }
- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- optionsBuilder.UseInMemoryDatabase("test");
- }
+ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseInMemoryDatabase("test");
}
}
diff --git a/test/UnitOfWork.Tests/UnitOfWork.Tests.csproj b/test/UnitOfWork.Tests/UnitOfWork.Tests.csproj
index 1597ff6..e9dfcfa 100644
--- a/test/UnitOfWork.Tests/UnitOfWork.Tests.csproj
+++ b/test/UnitOfWork.Tests/UnitOfWork.Tests.csproj
@@ -5,10 +5,11 @@
-
-
+
+
+
-
+
all
runtime; build; native; contentfiles; analyzers