diff --git a/src/eQuantic.Core.Data.EntityFramework.MongoDb/Repository/UnitOfWork.cs b/src/eQuantic.Core.Data.EntityFramework.MongoDb/Repository/UnitOfWork.cs
index 8e38967..9da4ad4 100644
--- a/src/eQuantic.Core.Data.EntityFramework.MongoDb/Repository/UnitOfWork.cs
+++ b/src/eQuantic.Core.Data.EntityFramework.MongoDb/Repository/UnitOfWork.cs
@@ -1,243 +1,19 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Threading;
-using System.Threading.Tasks;
+using eQuantic.Core.Data.EntityFramework.Repository;
using eQuantic.Core.Data.Repository;
-using eQuantic.Core.Data.Repository.Options;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.DependencyInjection;
namespace eQuantic.Core.Data.EntityFramework.MongoDb.Repository;
-public abstract class UnitOfWork : IQueryableUnitOfWork
+///
+/// The MongoDB unit of work. All of the store-agnostic behaviour lives in
+/// ; this only supplies the MongoDB .
+///
+public abstract class UnitOfWork(IServiceProvider serviceProvider, DbContext context)
+ : EntityFrameworkUnitOfWork(serviceProvider, context)
{
- protected readonly IServiceProvider ServiceProvider;
- ///
- /// The context
- ///
- protected readonly DbContext Context;
-
- ///
- /// The disposed
- ///
- protected bool Disposed;
-
- ///
- /// Initializes a new instance of the class
- ///
- ///
- /// The context
- protected UnitOfWork(IServiceProvider serviceProvider, DbContext context)
- {
- ServiceProvider = serviceProvider;
- Context = context;
- }
-
- public int Commit()
- {
- return Context.SaveChanges();
- }
-
- public int CommitAndRefreshChanges()
- {
- var changes = 0;
- var saveFailed = false;
-
- do
- {
- try
- {
- changes = Context.SaveChanges();
-
- saveFailed = false;
- }
- catch (DbUpdateConcurrencyException ex)
- {
- saveFailed = true;
-
- ex.Entries.ToList()
- .ForEach(entry => entry.OriginalValues.SetValues(entry.GetDatabaseValues()!));
- }
- } while (saveFailed);
-
- return changes;
- }
-
- public async Task CommitAndRefreshChangesAsync(CancellationToken cancellationToken = default)
- {
- var changes = 0;
- var saveFailed = false;
-
- do
- {
- try
- {
- changes = await Context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
-
- saveFailed = false;
- }
- catch (DbUpdateConcurrencyException ex)
- {
- saveFailed = true;
-
- ex.Entries.ToList()
- .ForEach(entry => entry.OriginalValues.SetValues(entry.GetDatabaseValues()!));
- }
- } while (saveFailed);
-
- return changes;
- }
-
- public async Task CommitAsync(CancellationToken cancellationToken = default)
- {
- return await Context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
- }
-
- public int Commit(Action options)
- {
- return Commit();
- }
-
- public int CommitAndRefreshChanges(Action options)
- {
- return CommitAndRefreshChanges();
- }
-
- public Task CommitAndRefreshChangesAsync(Action options, CancellationToken cancellationToken = default)
- {
- return CommitAndRefreshChangesAsync(cancellationToken);
- }
-
- public Task CommitAsync(Action options, CancellationToken cancellationToken = default)
- {
- return CommitAsync(cancellationToken);
- }
-
- public void ApplyCurrentValues(TEntity original, TEntity current) where TEntity : class, IEntity
- {
- ((Set)InternalCreateSet()).ApplyCurrentValues(original, current);
- }
-
- public void Attach(TEntity item) where TEntity : class, IEntity
- {
- ((Set)InternalCreateSet()).Attach(item);
- }
-
- public void LoadCollection(TEntity item,
- Expression>> navigationProperty,
- Expression>? filter = null) where TEntity : class where TElement : class
- {
- if (filter != null)
- {
- Context.Entry(item).Collection(navigationProperty).Query().Where(filter).Load();
- }
- else
- {
- Context.Entry(item).Collection(navigationProperty).Load();
- }
- }
-
- public async Task LoadCollectionAsync(TEntity item,
- Expression>> navigationProperty,
- Expression>? filter = null) where TEntity : class where TElement : class
- {
- if (filter != null)
- {
- await Context.Entry(item).Collection(navigationProperty).Query().Where(filter).LoadAsync().ConfigureAwait(false);
- }
- else
- {
- await Context.Entry(item).Collection(navigationProperty).LoadAsync().ConfigureAwait(false);
- }
- }
-
- public void Reload(TEntity item) where TEntity : class
- {
- var entry = Context.Entry(item);
- entry.CurrentValues.SetValues(entry.OriginalValues);
- entry.Reload();
- }
-
- public void RollbackChanges()
- {
- // set all entities in change tracker
- // as 'unchanged state'
- Context?.ChangeTracker.Entries()
- .ToList()
- .ForEach(entry => entry.State = EntityState.Unchanged);
- }
-
- public void SetModified(TEntity item) where TEntity : class
- {
- //this operation also attach item in object state manager
- Context.Entry(item).State = EntityState.Modified;
- }
-
- public virtual SaveOptions GetSaveOptions()
- {
- return new SaveOptions();
- }
-
- public virtual IRepository GetRepository()
- where TEntity : class, IEntity
- {
- return ServiceProvider.GetRequiredService>();
- }
-
- public IAsyncRepository GetAsyncRepository()
- where TEntity : class, IEntity
- {
- return ServiceProvider.GetRequiredService>();
- }
-
- public Data.Repository.ISet CreateSet() where TEntity : class, IEntity => InternalCreateSet();
-
- public IQueryableRepository GetQueryableRepository()
- where TEntity : class, IEntity
- {
- return ServiceProvider.GetRequiredService>();
- }
-
- public IAsyncQueryableRepository GetAsyncQueryableRepository()
- where TEntity : class, IEntity
- {
- return ServiceProvider.GetRequiredService>();
- }
-
- internal DbContext GetDbContext() => Context;
-
- internal Data.Repository.ISet InternalCreateSet() where TEntity : class, IEntity =>
+ protected override Data.Repository.ISet CreateSetCore() =>
new Set(ServiceProvider, Context);
-
- ///
- /// Disposes this instance
- ///
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- ///
- /// Disposes the disposing
- ///
- /// The disposing
- protected virtual void Dispose(bool disposing)
- {
- if (Disposed)
- {
- return;
- }
-
- if (disposing)
- {
- Context?.Dispose();
- }
-
- Disposed = true;
- }
}
public abstract class UnitOfWork(IServiceProvider serviceProvider, TDbContext context)
diff --git a/src/eQuantic.Core.Data.EntityFramework.MongoDb/eQuantic.Core.Data.EntityFramework.MongoDb.Net10.csproj b/src/eQuantic.Core.Data.EntityFramework.MongoDb/eQuantic.Core.Data.EntityFramework.MongoDb.Net10.csproj
index 2a64b88..6fb0a41 100644
--- a/src/eQuantic.Core.Data.EntityFramework.MongoDb/eQuantic.Core.Data.EntityFramework.MongoDb.Net10.csproj
+++ b/src/eQuantic.Core.Data.EntityFramework.MongoDb/eQuantic.Core.Data.EntityFramework.MongoDb.Net10.csproj
@@ -4,7 +4,7 @@
Core Data library for Entity Framework and Mongo DB
eQuantic.Core.Data.EntityFramework.MongoDb
- 10.1.0.0
+ 10.2.0.0
net10.0
eQuantic.Core.Data.EntityFramework.MongoDb
eQuantic.Core.Data.EntityFramework.MongoDb
@@ -12,8 +12,8 @@
Entity ignorant persistance with Repository Pattern for Entity
Framework
- 10.1.0.0
- 10.1.0.0
+ 10.2.0.0
+ 10.2.0.0
enable
enable
diff --git a/src/eQuantic.Core.Data.EntityFramework.MongoDb/eQuantic.Core.Data.EntityFramework.MongoDb.Net8.csproj b/src/eQuantic.Core.Data.EntityFramework.MongoDb/eQuantic.Core.Data.EntityFramework.MongoDb.Net8.csproj
index 76c7c37..8f03163 100644
--- a/src/eQuantic.Core.Data.EntityFramework.MongoDb/eQuantic.Core.Data.EntityFramework.MongoDb.Net8.csproj
+++ b/src/eQuantic.Core.Data.EntityFramework.MongoDb/eQuantic.Core.Data.EntityFramework.MongoDb.Net8.csproj
@@ -4,7 +4,7 @@
Core Data library for Entity Framework and Mongo DB
eQuantic.Core.Data.EntityFramework.MongoDb
- 8.2.0.0
+ 8.3.0.0
net8.0
eQuantic.Core.Data.EntityFramework.MongoDb
eQuantic.Core.Data.EntityFramework.MongoDb
@@ -12,8 +12,8 @@
Entity ignorant persistance with Repository Pattern for Entity
Framework
- 8.2.0.0
- 8.2.0.0
+ 8.3.0.0
+ 8.3.0.0
enable
enable
diff --git a/src/eQuantic.Core.Data.EntityFramework/Repository/EntityFrameworkUnitOfWork.cs b/src/eQuantic.Core.Data.EntityFramework/Repository/EntityFrameworkUnitOfWork.cs
new file mode 100644
index 0000000..eaf8ecf
--- /dev/null
+++ b/src/eQuantic.Core.Data.EntityFramework/Repository/EntityFrameworkUnitOfWork.cs
@@ -0,0 +1,249 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Threading;
+using System.Threading.Tasks;
+using eQuantic.Core.Data.Repository;
+using eQuantic.Core.Data.Repository.Options;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace eQuantic.Core.Data.EntityFramework.Repository;
+
+///
+/// The shared, provider-agnostic implementation for the document
+/// (non-relational) EF Core providers. It carries every unit-of-work member that does not depend on the
+/// store; each provider supplies only its own entity set by overriding .
+/// The relational providers keep their own unit of work (it also is a raw-SQL executor).
+///
+public abstract class EntityFrameworkUnitOfWork : IQueryableUnitOfWork
+{
+ /// The service provider used to resolve repositories.
+ protected readonly IServiceProvider ServiceProvider;
+
+ /// The underlying .
+ protected readonly DbContext Context;
+
+ /// Whether this instance has been disposed.
+ protected bool Disposed;
+
+ /// Initializes a new instance of the class.
+ /// The service provider.
+ /// The context.
+ protected EntityFrameworkUnitOfWork(IServiceProvider serviceProvider, DbContext context)
+ {
+ ServiceProvider = serviceProvider;
+ Context = context;
+ }
+
+ /// Creates the provider-specific entity set for .
+ /// The entity type.
+ /// The provider's (a ).
+ protected abstract Data.Repository.ISet CreateSetCore() where TEntity : class, IEntity;
+
+ public int Commit()
+ {
+ return Context.SaveChanges();
+ }
+
+ public int CommitAndRefreshChanges()
+ {
+ var changes = 0;
+ var saveFailed = false;
+
+ do
+ {
+ try
+ {
+ changes = Context.SaveChanges();
+
+ saveFailed = false;
+ }
+ catch (DbUpdateConcurrencyException ex)
+ {
+ saveFailed = true;
+
+ ex.Entries.ToList()
+ .ForEach(entry => entry.OriginalValues.SetValues(entry.GetDatabaseValues()));
+ }
+ } while (saveFailed);
+
+ return changes;
+ }
+
+ public async Task CommitAndRefreshChangesAsync(CancellationToken cancellationToken = default)
+ {
+ var changes = 0;
+ var saveFailed = false;
+
+ do
+ {
+ try
+ {
+ changes = await Context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
+
+ saveFailed = false;
+ }
+ catch (DbUpdateConcurrencyException ex)
+ {
+ saveFailed = true;
+
+ ex.Entries.ToList()
+ .ForEach(entry => entry.OriginalValues.SetValues(entry.GetDatabaseValues()));
+ }
+ } while (saveFailed);
+
+ return changes;
+ }
+
+ public async Task CommitAsync(CancellationToken cancellationToken = default)
+ {
+ return await Context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
+ }
+
+ public int Commit(Action options)
+ {
+ return Commit();
+ }
+
+ public int CommitAndRefreshChanges(Action options)
+ {
+ return CommitAndRefreshChanges();
+ }
+
+ public Task CommitAndRefreshChangesAsync(Action options, CancellationToken cancellationToken = default)
+ {
+ return CommitAndRefreshChangesAsync(cancellationToken);
+ }
+
+ public Task CommitAsync(Action options, CancellationToken cancellationToken = default)
+ {
+ return CommitAsync(cancellationToken);
+ }
+
+ public void ApplyCurrentValues(TEntity original, TEntity current) where TEntity : class, IEntity
+ {
+ ((SetBase)CreateSetCore()).ApplyCurrentValues(original, current);
+ }
+
+ public void Attach(TEntity item) where TEntity : class, IEntity
+ {
+ ((SetBase)CreateSetCore()).Attach(item);
+ }
+
+ public void LoadCollection(TEntity item,
+ Expression>> navigationProperty,
+ Expression> filter = null) where TEntity : class where TElement : class
+ {
+ if (filter != null)
+ {
+ Context.Entry(item).Collection(navigationProperty).Query().Where(filter).Load();
+ }
+ else
+ {
+ Context.Entry(item).Collection(navigationProperty).Load();
+ }
+ }
+
+ public async Task LoadCollectionAsync(TEntity item,
+ Expression>> navigationProperty,
+ Expression> filter = null) where TEntity : class where TElement : class
+ {
+ if (filter != null)
+ {
+ await Context.Entry(item).Collection(navigationProperty).Query().Where(filter).LoadAsync().ConfigureAwait(false);
+ }
+ else
+ {
+ await Context.Entry(item).Collection(navigationProperty).LoadAsync().ConfigureAwait(false);
+ }
+ }
+
+ public void Reload(TEntity item) where TEntity : class
+ {
+ var entry = Context.Entry(item);
+ entry.CurrentValues.SetValues(entry.OriginalValues);
+ entry.Reload();
+ }
+
+ public void RollbackChanges()
+ {
+ // set all entities in change tracker as 'unchanged state'
+ Context?.ChangeTracker.Entries()
+ .ToList()
+ .ForEach(entry => entry.State = EntityState.Unchanged);
+ }
+
+ public void SetModified(TEntity item) where TEntity : class
+ {
+ // this operation also attaches item in the object state manager
+ Context.Entry(item).State = EntityState.Modified;
+ }
+
+ public virtual SaveOptions GetSaveOptions()
+ {
+ return new SaveOptions();
+ }
+
+ public virtual IRepository GetRepository()
+ where TEntity : class, IEntity
+ {
+ return ServiceProvider.GetRequiredService>();
+ }
+
+ public IAsyncRepository GetAsyncRepository()
+ where TEntity : class, IEntity
+ {
+ return ServiceProvider.GetRequiredService>();
+ }
+
+ public Data.Repository.ISet CreateSet() where TEntity : class, IEntity => CreateSetCore();
+
+ public IQueryableRepository GetQueryableRepository()
+ where TEntity : class, IEntity
+ {
+ return ServiceProvider.GetRequiredService>();
+ }
+
+ public IAsyncQueryableRepository GetAsyncQueryableRepository()
+ where TEntity : class, IEntity
+ {
+ return ServiceProvider.GetRequiredService>();
+ }
+
+ internal DbContext GetDbContext() => Context;
+
+ /// Disposes this instance.
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// Disposes the managed resources.
+ /// Whether to dispose managed resources.
+ protected virtual void Dispose(bool disposing)
+ {
+ if (Disposed)
+ {
+ return;
+ }
+
+ if (disposing)
+ {
+ Context?.Dispose();
+ }
+
+ Disposed = true;
+ }
+}
+
+///
+/// The strongly-typed that a document provider's unit of work
+/// derives from over its concrete .
+///
+/// The context type.
+public abstract class EntityFrameworkUnitOfWork(IServiceProvider serviceProvider, TDbContext context)
+ : EntityFrameworkUnitOfWork(serviceProvider, context)
+ where TDbContext : DbContext;
diff --git a/src/eQuantic.Core.Data.EntityFramework/eQuantic.Core.Data.EntityFramework.Net10.csproj b/src/eQuantic.Core.Data.EntityFramework/eQuantic.Core.Data.EntityFramework.Net10.csproj
index ab20736..4c4e58c 100644
--- a/src/eQuantic.Core.Data.EntityFramework/eQuantic.Core.Data.EntityFramework.Net10.csproj
+++ b/src/eQuantic.Core.Data.EntityFramework/eQuantic.Core.Data.EntityFramework.Net10.csproj
@@ -4,7 +4,7 @@
Core Data library for Entity Framework
eQuantic.Core.Data.EntityFramework
- 10.1.0.0
+ 10.2.0.0
net10.0
eQuantic.Core.Data.EntityFramework
eQuantic.Core.Data.EntityFramework
@@ -12,8 +12,8 @@
Entity ignorant persistance with Repository Pattern for Entity
Framework
- 10.1.0.0
- 10.1.0.0
+ 10.2.0.0
+ 10.2.0.0
diff --git a/src/eQuantic.Core.Data.EntityFramework/eQuantic.Core.Data.EntityFramework.Net8.csproj b/src/eQuantic.Core.Data.EntityFramework/eQuantic.Core.Data.EntityFramework.Net8.csproj
index ac1500b..d6d78fc 100644
--- a/src/eQuantic.Core.Data.EntityFramework/eQuantic.Core.Data.EntityFramework.Net8.csproj
+++ b/src/eQuantic.Core.Data.EntityFramework/eQuantic.Core.Data.EntityFramework.Net8.csproj
@@ -4,7 +4,7 @@
Core Data library for Entity Framework
eQuantic.Core.Data.EntityFramework
- 8.2.0.0
+ 8.3.0.0
net8.0
eQuantic.Core.Data.EntityFramework
eQuantic.Core.Data.EntityFramework
@@ -12,8 +12,8 @@
Entity ignorant persistance with Repository Pattern for Entity
Framework
- 8.2.0.0
- 8.2.0.0
+ 8.3.0.0
+ 8.3.0.0
diff --git a/src/eQuantic.Core.Data.EntityFramework/eQuantic.Core.Data.EntityFramework.csproj b/src/eQuantic.Core.Data.EntityFramework/eQuantic.Core.Data.EntityFramework.csproj
index 776afc9..fe4806a 100644
--- a/src/eQuantic.Core.Data.EntityFramework/eQuantic.Core.Data.EntityFramework.csproj
+++ b/src/eQuantic.Core.Data.EntityFramework/eQuantic.Core.Data.EntityFramework.csproj
@@ -4,15 +4,15 @@
Core Data library for Entity Framework
eQuantic.Core.Data.EntityFramework
- 4.5.0.0
+ 4.6.0.0
net8.0;net10.0
eQuantic.Core.Data.EntityFramework
eQuantic.Core.Data.EntityFramework
eQuantic;Core;Data;Library;Repository;Pattern
Entity ignorant persistance with Repository Pattern for Entity Framework
- 4.5.0.0
- 4.5.0.0
+ 4.6.0.0
+ 4.6.0.0