EntityCloner.Microsoft.EntityFrameworkCore 8.0.0

dotnet add package EntityCloner.Microsoft.EntityFrameworkCore --version 8.0.0                
NuGet\Install-Package EntityCloner.Microsoft.EntityFrameworkCore -Version 8.0.0                
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="EntityCloner.Microsoft.EntityFrameworkCore" Version="8.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add EntityCloner.Microsoft.EntityFrameworkCore --version 8.0.0                
#r "nuget: EntityCloner.Microsoft.EntityFrameworkCore, 8.0.0"                
#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 EntityCloner.Microsoft.EntityFrameworkCore as a Cake Addin
#addin nuget:?package=EntityCloner.Microsoft.EntityFrameworkCore&version=8.0.0

// Install EntityCloner.Microsoft.EntityFrameworkCore as a Cake Tool
#tool nuget:?package=EntityCloner.Microsoft.EntityFrameworkCore&version=8.0.0                

EntityCloner.Microsoft.EntityFrameworkCore

Build Status NuGet NuGet

Summary

Cloning entities using EntityFrameworkCore configuration.

This library is Cross-platform, supporting net6.0, net7.0 and net8.0.

Installing EntityCloner.Microsoft.EntityFrameworkCore

You should install EntityCloner.Microsoft.EntityFrameworkCore with NuGet:

Install-Package EntityCloner.Microsoft.EntityFrameworkCore

Or via the .NET Core command line interface:

dotnet add package EntityCloner.Microsoft.EntityFrameworkCore

Either commands, from Package Manager Console or .NET Core CLI, will download and install EntityCloner.Microsoft.EntityFrameworkCore and all required dependencies.

Dependencies

Usage

This package provides two extension methods for DbContext:

  • Task<TEntity> CloneAsync<TEntity>(this DbContext source, params object[] primaryKey)

  • Task<TEntity> CloneAsync<TEntity>(this DbContext source, Func<IClonableQueryable<TEntity>, IClonableQueryable<TEntity>> includeQuery, params object[] primaryKey)

These extension methods supports cloning an entity. Be aware: the cloned entity is not tracked by the ChangeTracker of EntityFrameworkCore. You should add it manually to the DbSet.

Only clone the entities you want to clone

If you provide IncludeQuery configuration, then the included entities will be cloned too. The Include and ThenInclude works same way as EntityFrameworkCore for querying with Linq.

Based on EntityFrameworkCore configuration Model

It will clone the entity with related entities based on EntityFrameworkCore configuration model.

Resetting properties to default value

During cloning, all PrimaryKey, ForeignKey (except for some exceptions) and ConcurrencyToken properties will be reset to default values

If a ForeignKey entity is not included, then the ForeignKey property will not be reset. This is for example in cases when you have a ForeignKey to an entity from a selection list.

Support for Composite PrimaryKeys

It also supports primarty keys based on multiple properties.

Support for IQueryable<T> and (list of) plain entities

It also supports plain classes, IQueryable<T> and all type of lists like T[], IEnumerables<T>, IList<T> ICollection<T> and the implementation variants of it.

The only requirement is, that the entity should be part of the model configuration of EntityFrameworkCore.

To use it:

...
using EntityCloner.Microsoft.EntityFrameworkCore.EntityFrameworkCore.SqlServer;

public class YourClass
{
	   
	// This method gets called by the runtime. Use this method to add services to the container.
	public async Task YourMethod(DbContext dbContext)
	{
		var entityId = 10;

		// To clone only the entity:
		var clonedOrderEntity = await dbContext.CloneAsync<Order>(entityId);

		// To clone entity with related data
		var clonedOrderEntityWithRelatedEntities = await dbContext.CloneAsync<Order>(
			includeQuery => includeQuery
				.Include(o => o.OrderLines)
					.ThenInclude(ol => ol.Discounts)
				.Include(o => o.Customer)
					.ThenInclude(x => x.CustomerAddresses)
				.Include(o => o.Customer)
					.ThenInclude(x => x.Invoices) 
						.ThenInclude(x => x.InvoiceLines),
			entityId);

		// To clone using IQueryable
		var entityId = 10;
		var query = DbSet<TestEntity>.AsNoTracking()
				.Include(o => o.OrderLines)
					.ThenInclude(ol => ol.Discounts)
				.Include(o => o.Customer)
					.ThenInclude(x => x.CustomerAddresses)
				.Include(o => o.Customer)
					.ThenInclude(x => x.Invoices) 
						.ThenInclude(x => x.InvoiceLines)
				.Where(o => o.Id == entityId);

		var clonedOrderEntityViaQueryable = await dbContext.CloneAsync(query);

		// To clone using entity
		var entityId = 10;
		var entity = await DbSet<TestEntity>.AsNoTracking()
				.Include(o => o.OrderLines)
					.ThenInclude(ol => ol.Discounts)
				.Include(o => o.Customer)
					.ThenInclude(x => x.CustomerAddresses)
				.Include(o => o.Customer)
					.ThenInclude(x => x.Invoices) 
						.ThenInclude(x => x.InvoiceLines)
				.Where(o => o.Id == entityId)
				.SingleAsync();

		var clonedOrderEntityViaEntity = await dbContext.CloneAsync(entity);

		// To clone using list of entities
		var entityId = 10;
		var entities = await DbSet<TestEntity>.AsNoTracking()
				.Include(o => o.OrderLines)
					.ThenInclude(ol => ol.Discounts)
				.Include(o => o.Customer)
					.ThenInclude(x => x.CustomerAddresses)
				.Include(o => o.Customer)
					.ThenInclude(x => x.Invoices) 
						.ThenInclude(x => x.InvoiceLines)
				.Where(o => o.Id == entityId)
				.ToListAsync();

		var clonedOrderEntitiesViaList = await dbContext.CloneAsync(entities);
	}
}

Debugging

If you want to debug the source code, thats possible. SourceLink is enabled. To use it, you have to change Visual Studio Debugging options:

Debug ⇒ Options ⇒ Debugging ⇒ General

Set the following settings:

[  ] Enable Just My Code

[X] Enable .NET Framework source stepping

[X] Enable source server support

[X] Enable source link support

Now you can use 'step into' (F11).

Product Compatible and additional computed target framework versions.
.NET 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 is compatible.  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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on EntityCloner.Microsoft.EntityFrameworkCore:

Package Downloads
DataAccessClient

Provides interfaces for Data Access with IRepository<T> and IUnitOfWork. Also provides haviorial interfaces for entities like IIdentifiable, ICreatable, IModifiable, ISoftDeletable, ITranslatable, ILocalizable, ITenantScopable and IRowVersioned. Last but not least provides some types for Exceptions and searching capabilities like Filtering,Paging, Sorting and Includes.

DataAccessClient.EntityFrameworkCore.SqlServer

Provides implementation for Data Access with EntityFrameworkCore.SqlServer. It provides implementation for IRepository<T> and DbContext. It also provides extension methods for IServiceCollection to easily adding types to .NET Core DependencyInjection. Is also supports using multiple DbContexts within same IUnitOfWork.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
8.0.0 7,868 1/13/2024
7.1.0 11,568 7/18/2023
7.0.0 6,749 11/10/2022
6.0.0 9,841 11/15/2021
5.0.0 12,780 11/11/2020
0.0.4 3,049 5/27/2020
0.0.3 806 4/7/2020
0.0.2 2,999 4/2/2020
0.0.1 867 4/1/2020