Giter VIP home page Giter VIP logo

Comments (5)

leonardoporro avatar leonardoporro commented on May 25, 2024 1

So, the mapper works with two concepts, the DTO and the Entity which may be the same type, or not.

For example:

  • User to User map / dto: User and entity: User.
  • UserDTO to User map / dto: UserDTO and entity User.

Mapper then will:

  • Load root Entity along with [Compositon] children recursively and only the Id of [Aggregation] children (the graph).
  • Start traversing the graph and copying the properties.
    For [Aggregation]
  • Copy only the Id
  • Mark the Entity as Unchanged.
  • Do not recurse! Aggregations end here.
    For [Composition]
  • If DTO exists and Entity doesn't, mark as Added
  • If DTO doesn't exist and Entity does, mark as Deleted
  • If both exists, mark as Modified.
  • Continue recursively with the rest of the Complex or Collection properties.

[Aggregation] are supossed to be independent entities/graphs that the entity is referring to. And shouldn't be added/deleted along with it. e.g.: Invoice -> InvoiceType
That's why only Id is mapped for aggregations and is marked as Unmodified. If the aggregated entity doesn't exists, an fk error is thrown when saving.

[Composition] are entities that form part of the same concept and should be updated/deleted with the root entity.
e.g.: Invoice -> InvoiceDetail.

Another interesting thing. Given the previous DTO and Entity definitions, values are always copied, even when they are the same type. The User that you passed to the MapAsync method is not the same that gets attached to the context.
The attached one comes from the initial query or is instantiated by the mapper, and it's returned by the MapAsync method.
var attachedUser = await db.MapAsync<User>(detachedUser);
In this example, attached and detached users are not the same instance.

In this your case, MapAsync will:

  • Load the root, but the key is empty so it will create a new User.
  • Copy Id, Name, DoB and other simple values
  • Recursively iterate Roles
  • There will be 1 role DTO and 0 role Entities, so it will create a Role and since it is an [Aggregation] it will copy the Id and mark it as Unmodified.

This is a very high level description, as there much more, like circle dependencies (BackReference in the code), type configuration, mapping configuration, the dynamic code, etc.

Feel free to ask on a certain topic if you are interested on it.

from detached-mapper.

leonardoporro avatar leonardoporro commented on May 25, 2024

Yes it is. I double checked just in case, this is the working code:

            TestDbContext db = await TestDbContext.CreateAsync();

            Role role = new Role() { Name = "Test" };
            db.Roles.Add(role);
            await db.SaveChangesAsync();

            // Create user and assign existing role
            User user = new() { Name = "Example" };
            user.Roles = new List<Role>(); // null reference here! in the old code.
            user.Roles.Add(role);

            await db.MapAsync<User>(user);

            await db.SaveChangesAsync();
   
           // result will contain an user with the assigned role
            var result = db.Users.Where(u => u.Name == "Example").FirstOrDefault();
       

from detached-mapper.

MaRRiK74 avatar MaRRiK74 commented on May 25, 2024

Thanks for the quick response. The null ref was not the issue on my side (my model always creates a new list).
I had missed something elsewhere. So this part does work, I wanted to close/delete this issue but you already responded :-)

But now I am facing the issue that after saving the dbcontext, the PK of the parent Item is always '0' in this case the user.Id is always 0. Is there an option to tell detached-mapper to return the value which was assigned?

from detached-mapper.

leonardoporro avatar leonardoporro commented on May 25, 2024

Thanks for the quick response. The null ref was not the issue on my side (my model always creates a new list). I had missed something elsewhere. So this part does work, I wanted to close/delete this issue but you already responded :-)

But now I am facing the issue that after saving the dbcontext, the PK of the parent Item is always '0' in this case the user.Id is always 0. Is there an option to tell detached-mapper to return the value which was assigned?

Sorry, we were writting posts at the same time, but I anwsered your question over there.
The instance that you pass to MapAsync is your "DTO", please take a look at the MapAsync return value and let me know if you can't find your Id there.

from detached-mapper.

MaRRiK74 avatar MaRRiK74 commented on May 25, 2024

Ah the return value, thanks for pointing that out! With that I can work something out. Many thanks again.

from detached-mapper.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.