DotNetBrightener.Mapper.Mapping.EFCore 2026.0.2

There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package DotNetBrightener.Mapper.Mapping.EFCore --version 2026.0.2
                    
NuGet\Install-Package DotNetBrightener.Mapper.Mapping.EFCore -Version 2026.0.2
                    
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="DotNetBrightener.Mapper.Mapping.EFCore" Version="2026.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DotNetBrightener.Mapper.Mapping.EFCore" Version="2026.0.2" />
                    
Directory.Packages.props
<PackageReference Include="DotNetBrightener.Mapper.Mapping.EFCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add DotNetBrightener.Mapper.Mapping.EFCore --version 2026.0.2
                    
#r "nuget: DotNetBrightener.Mapper.Mapping.EFCore, 2026.0.2"
                    
#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.
#:package DotNetBrightener.Mapper.Mapping.EFCore@2026.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=DotNetBrightener.Mapper.Mapping.EFCore&version=2026.0.2
                    
Install as a Cake Addin
#tool nuget:?package=DotNetBrightener.Mapper.Mapping.EFCore&version=2026.0.2
                    
Install as a Cake Tool

DotNetBrightener.Mapper.Mapping.EFCore

Copyright © 2017 - 2026 Vampire Coder (formerly DotnetBrightener)

DotNetBrightener.Mapper.Mapping.EFCore adds Entity Framework Core helpers on top of DotNetBrightener.Mapper.Mapping.

It covers two main scenarios:

  • SQL-translatable projection from IQueryable<TSource> to generated mapping targets
  • custom async mapping for cases that cannot be translated to SQL

Install

dotnet add package DotNetBrightener.Mapper.Mapping.EFCore

Namespaces

using DotNetBrightener.Mapper;
using DotNetBrightener.Mapper.Mapping;
using DotNetBrightener.Mapper.Mapping.Configurations;
using DotNetBrightener.Mapper.Mapping.EFCore;

Generated Target Example

[MappingTarget<User>(GenerateToSource = true)]
public partial class UserDto;

Query Projection API

Use these methods when your mapping can be expressed through the generated Projection expression.

Available methods:

  • ToTargetsAsync<TSource, TTarget>(CancellationToken cancellationToken = default)
  • ToTargetsAsync<TTarget>(CancellationToken cancellationToken = default)
  • FirstAsync<TSource, TTarget>(CancellationToken cancellationToken = default)
  • FirstAsync<TTarget>(CancellationToken cancellationToken = default)
  • SingleAsync<TSource, TTarget>(CancellationToken cancellationToken = default)
  • SingleAsync<TTarget>(CancellationToken cancellationToken = default)

Example:

var users = await dbContext.Users
    .Where(x => x.IsActive)
    .ToTargetsAsync<User, UserDto>();

var inferredUsers = await dbContext.Users
    .Where(x => x.IsActive)
    .ToTargetsAsync<UserDto>();

var firstUser = await dbContext.Users
    .Where(x => x.Id == id)
    .FirstAsync<UserDto>();

var singleUser = await dbContext.Users
    .Where(x => x.Email == email)
    .SingleAsync<User, UserDto>();

Streaming

For streaming, use the projection API from DotNetBrightener.Mapper.Mapping and then switch to EF Core async enumeration:

await foreach (var user in dbContext.Users
    .Where(x => x.IsActive)
    .SelectTarget<UserDto>()
    .AsAsyncEnumerable())
{
    Console.WriteLine(user.Email);
}

Call SelectTarget(...) before AsAsyncEnumerable() so the projection is translated to SQL.

Custom Async Mapping

Use the custom async overloads when mapping needs extra logic after the normal property copy, such as:

  • injected services
  • API calls
  • non-SQL type conversions
  • other async work

These methods materialize the query first, then apply custom async mapping.

Available methods:

  • ToTargetsAsync<TSource, TTarget>(IMappingConfigurationAsyncInstance<TSource, TTarget> mapper, CancellationToken cancellationToken = default)
  • ToTargetsAsync<TSource, TTarget, TAsyncMapper>(CancellationToken cancellationToken = default)
  • FirstAsync<TSource, TTarget>(IMappingConfigurationAsyncInstance<TSource, TTarget> mapper, CancellationToken cancellationToken = default)
  • FirstAsync<TSource, TTarget, TAsyncMapper>(CancellationToken cancellationToken = default)
  • SingleAsync<TSource, TTarget>(IMappingConfigurationAsyncInstance<TSource, TTarget> mapper, CancellationToken cancellationToken = default)
  • SingleAsync<TSource, TTarget, TAsyncMapper>(CancellationToken cancellationToken = default)

Instance Mapper With DI

public sealed class UserMapper : IMappingConfigurationAsyncInstance<User, UserDto>
{
    private readonly IAvatarService _avatarService;

    public UserMapper(IAvatarService avatarService)
    {
        _avatarService = avatarService;
    }

    public async Task MapAsync(User source, UserDto target, CancellationToken cancellationToken = default)
    {
        target.AvatarUrl = await _avatarService.GetAvatarUrlAsync(source.Id, cancellationToken);
    }
}
var users = await dbContext.Users
    .Where(x => x.IsActive)
    .ToTargetsAsync<User, UserDto>(userMapper);

Static Async Mapper

public sealed class UserMapper : IMappingConfigurationAsync<User, UserDto>
{
    public static Task MapAsync(User source, UserDto target, CancellationToken cancellationToken = default)
    {
        target.DisplayName = $"{source.FirstName} {source.LastName}";
        return Task.CompletedTask;
    }
}
var users = await dbContext.Users
    .Where(x => x.IsActive)
    .ToTargetsAsync<User, UserDto, UserMapper>();

Update Existing Entities From Targets

This package also provides EF Core change-tracking helpers for updating entities from target DTOs.

Available methods:

  • UpdateFromTarget<TEntity, TTarget>(TTarget target, DbContext context)
  • UpdateFromTargetAsync<TEntity, TTarget>(TTarget target, DbContext context, CancellationToken cancellationToken = default)
  • UpdateFromTargetWithChanges<TEntity, TTarget>(TTarget target, DbContext context)

Example:

[MappingTarget<User>("PasswordHash", "CreatedAt", GenerateToSource = true)]
public partial class UpdateUserDto;

var entity = await dbContext.Users.FindAsync(id);
if (entity is null)
{
    return Results.NotFound();
}

entity.UpdateFromTarget(updateDto, dbContext);
await dbContext.SaveChangesAsync();

If you need to know which properties changed:

var result = entity.UpdateFromTargetWithChanges(updateDto, dbContext);

if (result.ChangedProperties.Any())
{
    logger.LogInformation(
        "Updated user {UserId}: {ChangedProperties}",
        entity.Id,
        string.Join(", ", result.ChangedProperties));
}

Notes

  • The projection-based methods use generated projection expressions and remain SQL-translatable.
  • The custom async mapper methods execute the EF Core query first, then run your custom mapping logic in memory.
  • The update helpers only copy properties that exist on both the target and the entity.

This package builds on the APIs from DotNetBrightener.Mapper.Mapping, including:

  • SelectTarget<TTarget>()
  • SelectTarget<TSource, TTarget>()
  • ToTarget(...)
  • ToSource(...)

Use those when you need provider-agnostic mapping helpers outside EF Core-specific async operations.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows 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
2026.0.3-preview-777 83 5/20/2026
2026.0.3-preview-773 106 4/24/2026
2026.0.3-preview-772 103 4/3/2026
2026.0.3-preview-770 101 4/2/2026
2026.0.3-preview-769 95 4/2/2026
2026.0.2 107 4/2/2026
2026.0.2-preview-v2026-0-1-755 94 3/27/2026
2026.0.2-preview-759 97 4/1/2026
2026.0.2-preview-758 100 3/29/2026
2026.0.2-preview-757 98 3/29/2026
2026.0.2-preview-756 97 3/27/2026
2026.0.2-preview-754 87 3/27/2026
2026.0.1 100 3/27/2026
2026.0.1-preview-752 98 3/26/2026
2026.0.1-preview-750 97 3/26/2026
2026.0.1-preview-749 100 3/25/2026
2026.0.1-preview-748 106 3/23/2026
2026.0.1-preview-742 98 3/22/2026
2025.0.11-preview-776 187 5/20/2026