All Projects → leonardoporro → Detached-Mapper

leonardoporro / Detached-Mapper

Licence: MIT license
An ORM friendly mapper. Allows saving entire entity graphs. Heavily inspired in GraphDiff and AutoMapper.

Programming Languages

C#
18002 projects

Projects that are alternatives of or similar to Detached-Mapper

Nebula.Admin
Destiny.Core.Flow是基于.Net Core,VUE前后分离,开发的一个开源Admin管理框架目前有以下模块:菜单管理、用户管理、角色管理、用户角色、角色权限等功能。
Stars: ✭ 254 (+185.39%)
Mutual labels:  efcore, ef-core, automapper
Entityframework Plus
Entity Framework Plus extends your DbContext with must-haves features: Include Filter, Auditing, Caching, Query Future, Batch Delete, Batch Update, and more
Stars: ✭ 1,848 (+1976.4%)
Mutual labels:  entity-framework, entityframework
Aspnetcore Ddd
Full ASP.NET Core 3.1 LTS application with DDD, CQRS and Event Sourcing
Stars: ✭ 88 (-1.12%)
Mutual labels:  entity-framework, automapper
Mapper
🔥 An Object-Object AutoMapper for TypeScript 🔥
Stars: ✭ 221 (+148.31%)
Mutual labels:  mapper, automapper
Abp Asp.net Boilerplate Project Cms
ABP module-zero +AdminLTE+Bootstrap Table+jQuery+Redis + sql server+quartz+hangfire权限管理系统
Stars: ✭ 677 (+660.67%)
Mutual labels:  entity-framework, automapper
Decision
Simple Decision System
Stars: ✭ 50 (-43.82%)
Mutual labels:  entity-framework, automapper
Mappinggenerator
🔄 "AutoMapper" like, Roslyn based, code fix provider that allows to generate mapping code in design time.
Stars: ✭ 831 (+833.71%)
Mutual labels:  mapper, automapper
AspNetCore.BookStore
ASP.NET Core application using Command Pattern and Repository Pattern
Stars: ✭ 121 (+35.96%)
Mutual labels:  efcore, automapper
BlazorEFCoreMultitenant
Examples of multitenancy using EF Core and Blazor.
Stars: ✭ 67 (-24.72%)
Mutual labels:  entity-framework, efcore
EntityFrameworkCore.Triggered
Triggers for EFCore. Respond to changes in your DbContext before and after they are committed to the database.
Stars: ✭ 361 (+305.62%)
Mutual labels:  entity-framework, efcore
ENLOCK
Efcore with no lock extention
Stars: ✭ 25 (-71.91%)
Mutual labels:  efcore, entityframework
Mockqueryable
Moking Entity Framework Core operations such ToListAsync, FirstOrDefaultAsync etc
Stars: ✭ 281 (+215.73%)
Mutual labels:  entity-framework, automapper
CodexMicroORM
An alternative to ORM's such as Entity Framework, offers light-weight database mapping to your existing CLR objects. Visit "Design Goals" on GitHub to see more rationale and guidance.
Stars: ✭ 32 (-64.04%)
Mutual labels:  entity-framework, entityframework
Clinicmanagement
Clinic management project using Asp.net mvc5
Stars: ✭ 74 (-16.85%)
Mutual labels:  entity-framework, automapper
Efcore.bulkextensions
Entity Framework Core Bulk Batch Extensions for Insert Update Delete Read (CRUD), Truncate and SaveChanges operations on SQL Server, PostgreSQL, SQLite
Stars: ✭ 2,295 (+2478.65%)
Mutual labels:  efcore, entityframework
Morphism
⚡ Type-safe data transformer for JavaScript, TypeScript & Node.js.
Stars: ✭ 336 (+277.53%)
Mutual labels:  mapper, automapper
Equinoxproject
Full ASP.NET Core 5 application with DDD, CQRS and Event Sourcing concepts
Stars: ✭ 5,120 (+5652.81%)
Mutual labels:  ef-core, automapper
EasyProfiler
This repo, provides query profiler for .Net
Stars: ✭ 99 (+11.24%)
Mutual labels:  efcore, ef-core
SapientGuardian.EntityFrameworkCore.MySql
MySQL database provider for Entity Framework Core
Stars: ✭ 54 (-39.33%)
Mutual labels:  entity-framework, efcore
EFSqlTranslator
A standalone linq to sql translator that can be used with EF and Dapper.
Stars: ✭ 51 (-42.7%)
Mutual labels:  entity-framework, efcore

Detached Banner

Map your DTOs directly to the DbContext

Play with Mapper in .Net Fiddle!
  • Attach graph of anonymous objects: link
  • Import json graph: link
Check related tools
Let me know if it works for you (or doesn't)!

Mappers

What is it

Hi!, I'm trying to build a fast, object-oriented mapper to simplify the task of saving disconected entities in web services. It was heavily inspired by GraphDiff, AutoMapper and other awesome libraries. Any fix or feedback is very welcome.

What does it solve

If you worked with .net apis long enought you have seen one or all of these situations:

Problem 1: Disconected entities state

When working with EntityFramework, NHibernate, or practically any other ORM that tracks entity states, there is a problem when persinsing non-tracked entities that comes usually from a deserialization (request, response, a file, another db, etc.) EF has the TrackGraph method, but the state of each entity needs to be specified manually. NHibernate has a Merge feature, but it merges everything, and sometimes there are associated entities that should not be modified.

Problem 2: Mapping Data transfer objects (DTOs) to Entities

To reduce data traffic and, improve the security and the readability of swagger models, many times DTOs are used, and often they are very similar to the original entity.

A manual mapping or a tool like AutoMapper is needed to convert the DTOs to entities, before attach them to the ORM context/session, but this library aims to do it automatically and save steps.

Problem 3: Patches (partial updates)

C# does not support an "Undefined" value, like JavaScript, that's why for partial updates, Null may be used for optional values. But in some cases, null needs to be persisted, to remove a previous field value or disconnect an existing relationship.

How it works

The main method of Detached is MapAsync. It receives an object or dictionary as a parameter, then loads the corresponding entity graph from the database (like GraphDiff does), and then copies the values from the given DTO and set the correct states.

Solution 1: Mapping DTOs to Entities

Detached can handle DTO-Entity, DTO-DTO and Entity-Entity mapping. There are important tasks when mapping entities, like checking back references and merging collections. So that, classes representing entities should be marked with the [Entity] attribute or configured with modelOptions.Configure<Entity>().IsEntity(). For EntityFramework, entities are marked automatically when the correspondng DbSet exists. More info on configuration, later in this doc.

Solution 2: Setting states - Compositions and Aggregations

Aggregations are the weak relations (B and A are independent), also known as "Has a". Compositions are the strong (B cannot exists without A), also known as "Owns a".

This can be configured using the [Aggregation] and [Composition] attributes on the corresponding properties or fluently using cs modelOptions.Configure<Entity>().Member(e => e.Member).Composition(). More info on configuration, later in this doc.

When mapping, detached will only modify the root entity (the one passed as a parameter) and all the related entities marked as compositions. Associations are just attached an marked as Unmodified. Assuming that associations exist, also helps reducing the ammount of data loaded for the comparison.

[Aggregation] -> Link to an existing entity, is marked as Unmodified. [Composition] -> Create or update the entity, is marked as Created/Updated/Deleted.

(Note: there is an internal parameter: MapperParameters.AggregationAction, that allows creating associated entities when they don't exist, this is used to import complex graphs from json without having to order by dependency).

Solution 3: DTOs and IPatch

Detached copies only the properties that match (or are configured) from the DTO to the Entity, other properties are not overwritten. For partial updates, a DTO with the needed properties may be created, or a Dictionary<string, object> can be passed as a parameter. It also maps anonymous objects.

Partial updates without manually creating new types are supported using the IPatch interface, the PatchProxyFactory and the PatchJsonConverter. IPatchs indicates when properties are dirty, and PatchJsonConverter can generate proxies of the classes that auto-implement IPatch and deserialize json using that proxy. More info on configuration, later in this doc.

Getting Started

Install Nu-Get package
Install-Package Detached.Mappers.EntityFramework -Version 6.0.2
Create your regular DbContext
public class TestDbContext : DbContext
{
    ...
}
Register dependencies

Detached needs a QueryProvider instance, that helps loading the current status of the entities to save and a Mapper instance that copies the given DTO/Entity state over the current entities. These services are added by calling UseDetached on DbContextBuilderOptions.

If working on ASP.NET, this is usually configured in the DI container at the beggining (Startup.cs).

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<MainDbContext>(cfg =>
    {
        ...
        cfg.UseDetached();
    });
} 
Perform a Map

The MapAsync extension method can be called to load current state and copy DTO values. MapAsync returns the persisted entity (that comes from the DB) with the updated values. No updates are persisted until SaveChanges is called().

User attachedUser = await dbContext.MapAsync<User>(new UserDTO { Id = 1, Name = "NewName" });
await dbContext.SaveChangesAsync();
Configuration

Associations must be configured as aggregations or compositions, so Detached can choose how to load and map them. In order to do this, use [Aggregation] or [Composition] attributes:

class Invoice
{
    [Composition]
    public List<Row> Rows { get; set; }
}

Or use MappingOptions when calling UseDetached to configure it:

services.AddDbContext<MainDbContext>(cfg =>
    {
        ...
        cfg.UseDetached(options => {
            options.Configure<Invoice>().Member(i => i.Rows).Composition();
        });
    });
Solution 3: Different approaches for Partial Updates

Approaches to perform partial updates:

1 - Use a DTO or a Dictionary or an Anonymous class that contains only the properties to update Mapper will copy only matching properties, as the other ones do not exist.

2 - Programatically implement IPatch interface, that allows to mark properties as dirty. Mapper will check the value of IPatch.IsSet before copying the property value.

3 - The Patch Type Proxy factory (Patch.Create) can be used to generate a new runtime type that inherits your class and implements IPatch automatically. This is done by overriding all property setters and adding an internal HashSet to keep the values, so that, All properties must be marked as Virtual; otherwise, the proxy factory wont't be able to override them.

When sending a JSON with undefined properties, serializer leave them with their default values and the "undefined" state is lost during deserialization. That's why PatchJsonConverter allows to automatically deserialize some classes into Patch Proxy types directly, tracking the "undefined" information in the form of IsSet() true/false calls.

See this library for source code and more info and samples: Patch Types

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].