Mindfire.EFRepository 2.1.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package Mindfire.EFRepository --version 2.1.1                
NuGet\Install-Package Mindfire.EFRepository -Version 2.1.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Mindfire.EFRepository" Version="2.1.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Mindfire.EFRepository --version 2.1.1                
#r "nuget: Mindfire.EFRepository, 2.1.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Mindfire.EFRepository as a Cake Addin
#addin nuget:?package=Mindfire.EFRepository&version=2.1.1

// Install Mindfire.EFRepository as a Cake Tool
#tool nuget:?package=Mindfire.EFRepository&version=2.1.1                

EFRepository

Use a LINQ-Enabled version of the Repository Pattern for Entity Framework

Interface

/// <summary>
/// Interface for interacting with data storage through the repository pattern
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public interface IRepository : IDisposable
{

	/// <summary>Event that fires when an item is added</summary>
	event Action<object> ItemAdding;

	/// <summary>Event that fires when an itemis modified</summary>
	event Action<object> ItemModifing;

	/// <summary>Event that fires when an item is deleted</summary>
	event Action<object> ItemDeleting;


	/// <summary>Queriable Entity</summary>
	IQueryable<TEntity> Query<TEntity>() where TEntity : class, new();

	/// <summary>
	/// Join another entity
	/// </summary>
	/// <typeparam name="TEntity"></typeparam>
	/// <returns></returns>
	IQueryable<TEntity> Join<TEntity>() where TEntity : class, new();

	/// <summary>
	/// Find an entity based on key(s)
	/// </summary>
	/// <param name="keys">The key(s) for the table</param>
	/// <returns>Entity if found, otherwise null</returns>
	TEntity FindOne<TEntity>(params object[] keys) where TEntity : class, new();

	/// <summary>
	/// Find an entity based on key(s)
	/// </summary>
	/// <param name="keys">The key(s) for the table</param>
	/// <returns>Entity if found, otherwise null</returns>
	Task<TEntity> FindOneAsync<TEntity>(params object[] keys) where TEntity : class, new();

	/// <summary>
	/// Adds entities explicily, even if a key is present
	/// </summary>
	/// <param name="values">Entities to add</param>
	void AddNew<TEntity>(params TEntity[] values) where TEntity : class, new();

	/// <summary>
	/// Add or update entities
	/// </summary>
	/// <remarks>
	/// If the key field of the entity is populated with a non-default value, the framework
	/// will assume that the entity is being updated.
	/// </remarks>
	/// <param name="values">Entities to add</param>
	void AddOrUpdate<TEntity>(params TEntity[] values) where TEntity : class, new();

	/// <summary>
	/// Add or update entities
	/// </summary>
	/// <param name="collection">Entities to add</param>
	void AddOrUpdate<TEntity>(IEnumerable<TEntity> collection) where TEntity : class, new();

	/// <summary>
	/// Delete a single entity by key(s)
	/// </summary>
	/// <param name="keys">The key(s) for the table</param>
	void DeleteOne<TEntity>(params object[] keys) where TEntity : class, new();

	/// <summary>
	/// Delete one or more entities
	/// </summary>
	/// <param name="values">Entities to delete</param>
	void Delete<TEntity>(params TEntity[] values) where TEntity : class, new();

	/// <summary>
	/// Delete one or more entities
	/// </summary>
	/// <param name="collection">Entities to delete</param>
	void Delete<TEntity>(IEnumerable<TEntity> collection) where TEntity : class, new();

	/// <summary>
	/// Save pending changes for the collection
	/// </summary>
	/// <returns>Number of affected entities</returns>
	int Save();

	/// <summary>
	/// Save pending changes for the collection async
	/// </summary>
	/// <returns>Number of affected entities</returns>
	Task<int> SaveAsync();

	/// <summary>
	/// Save pending changes for the collection async with cancellation
	/// </summary>
	/// <param name="cancellationToken">Cancelation Token</param>
	/// <returns>Number of affected entities</returns>
	Task<int> SaveAsync(CancellationToken cancellationToken = default);

	/// <summary>
	/// Begins a transaction at the specified isolation level
	/// </summary>
	/// <exception cref="InvalidOperationException">Will throw an excpetion if there is already a transaction in progress</exception>
	/// <param name="isolation">The desired transaction isolation level</param>
	void StartTransaction(IsolationLevel isolation);

	/// <summary>
	/// Begins a transaction at the specified isolation level
	/// </summary>
	/// <exception cref="InvalidOperationException">Will throw an excpetion if there is already a transaction in progress</exception>
	/// <param name="isolation">The desired transaction isolation level</param>
	/// <param name="cancellationToken">Optional cancelation token</param>
	void StartTransactionAsync(IsolationLevel isolation, CancellationToken cancellationToken = default);

	/// <summary>
	/// Begins a transaction at the ReadCommitted isolation level
	/// </summary>
	/// <exception cref="InvalidOperationException">Will throw an excpetion if there is already a transaction in progress</exception>
	void StartTransaction();

	/// <summary>
	/// Begins a transaction at the ReadCommitted isolation level
	/// </summary>
	/// <exception cref="InvalidOperationException">Will throw an excpetion if there is already a transaction in progress</exception>
	/// <param name="cancellationToken">Optional cancelation token</param>
	void StartTransactionAsync(CancellationToken cancellationToken = default);

	/// <summary>
	/// Commits an active transaction
	/// </summary>
	/// <exception cref="InvalidOperationException">Will throw an exception if there is not a transaction already in progress</exception>
	void CommitTransaction();

	/// <summary>
	/// Commits an active transaction
	/// </summary>
	/// <exception cref="InvalidOperationException">Will throw an exception if there is not a transaction already in progress</exception>
	/// <param name="cancellationToken">Optional cancelation token</param>
	void CommitTransactionAsync(CancellationToken cancellationToken = default);

	/// <summary>
	/// Rolls back the changes for a given transaction
	/// </summary>
	/// <exception cref="InvalidOperationException">Will throw an exception if there is not a transaction already in progress</exception>
	void RollbackTransaction();

	/// <summary>
	/// Rolls back the changes for a given transaction
	/// </summary>
	/// <exception cref="InvalidOperationException">Will throw an exception if there is not a transaction already in progress</exception>
	/// <param name="cancellationToken">Optional cancelation token</param>
	void RollbackTransactionAsync(CancellationToken cancellationToken = default);

	void EnlistTransaction(IDbTransaction transaction);

	IDbTransaction GetCurrentTransaction();
}

Future Goals

  • Better handling of client-provided ID's
    • What is the expected behavior for AddOrUpdate on a new Client side generated ID?
    • Add an attribute?
  • Better handling of joining of other tables into the query
    • One to One
    • One to Many
    • Many to One
    • Many to Many
  • Better transactional support -- espeically for EF Core
  • Better handling of Child Objects
  • Better support for Transactions
    • Test to see if we're inside of a transaction?
    • If the transaction is already in progress, then throw on BeginTrans
    • Commit or Rollback or throw on dispose?
  • Concurrency
  • AddOrUpdate with a New object that uses an existing object as a relation
    • If you're not using lazy loading, a simple recursive add
    • If you are using lazy loading, then it's your responsibility?
  • Soft Deletes
  • Better support for Eager, Explicit, and Lazy Loading
Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 is compatible.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net452 is compatible.  net46 was computed.  net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2.3.5 2,031 5/20/2022
2.2.0 862 1/13/2022
2.1.1 874 1/12/2022
2.0.0 702 1/11/2022
2.0.0-alpha 930 10/7/2020
1.1.3 1,099 11/27/2019
1.1.1 1,121 11/13/2019
1.0.2 1,765 7/21/2017
1.0.1 1,404 6/19/2017
1.0.0-alpha 1,424 5/23/2017

Updated the interface to allow for using a single repository objects for multiple different types.
Updated to include a source generator that creates helper methods for filtering by object properties.