Comments (5)
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.
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.
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.
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.
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)
- Complex properties of entity (Owned entities) cannot be used with EFcore mapper HOT 3
- Issue with ComplexType when using EFCore 8.0 HOT 2
- Map keys to entities and vice versa HOT 1
- [NotMapped] Attribute causes a cast error HOT 2
- Use Alternate Keys (Business Keys) to connect disconnected graph as the primary keys are not part of DTO/Disconnected Entity.
- [NotMapped] Attribut
- Exception creating map on static property HOT 1
- Mapping EF child collection of entities with Identity HOT 5
- Upon inserting entities return the newly seeded values for primary keys HOT 3
- lncrease the verbosity of mapping errors HOT 1
- context disposed in MapAsync HOT 3
- No factory for Optional<Guid?> -> Guid HOT 13
- Map a collection of DTOs to entities HOT 4
- Invalid cast when mapping List<T> to Collection<T> (or any derived Collection) HOT 4
- Ignore Data Annotation HOT 5
- GraphQL and Detached mapper HOT 7
- Aggregation doesn't seem to work properly HOT 10
- Prerelease .Net 8 HOT 5
- Updating a composite collection removes one entry HOT 5
- MapperException: Can't find a concrete type for abstract type or interface HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from detached-mapper.