Skip to content

Commit 2e29098

Browse files
committed
Documenting entity key mapping configuration
1 parent 8dcbc82 commit 2e29098

File tree

3 files changed

+105
-2
lines changed

3 files changed

+105
-2
lines changed

docs/src/Entity-Mapping.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ Mapping to entities - an object with a member decorated with a [`KeyAttribute`](
22

33
### Entity Keys
44

5-
Members decorated with a `KeyAttribute` are not mapped, unless the mapping is a deep clone. Entity key values are usually generated by a data store, and some ORMs will throw an exception if a key value is updated in code.
5+
By default, members decorated with a `KeyAttribute` are not mapped, unless the mapping is a deep clone. Entity key values are usually generated by a data store, and some ORMs will ignore key value updates, or in some cases, throw an exception.
66

7-
If you need to map to a `KeyAttribute` member, you can override this behaviour by configuring a [custom data source](/configuration/Member-Values).
7+
If you need to map `KeyAttribute` members, you can [configure the behaviour](/configuration/Entity-Mapping) that suits your needs, or configure a [custom data source](/configuration/Member-Values).
88

99
### Optional Related Entity Keys
1010

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
By default, members decorated with a `KeyAttribute` are not mapped, unless the mapping is a deep clone. Entity key values are usually generated by a data store, and some ORMs will ignore key value updates, or in some cases, throw an exception.
2+
3+
```cs
4+
// Retrieve the existing Customer entity:
5+
var customer = await dbContext
6+
.Customers
7+
.FirstOrDefaultAsync(c => c.Id == customerDto.Id);
8+
9+
if (customer == null)
10+
{
11+
// Deal with Customer not found
12+
}
13+
14+
// Update the Customer from the DTO - this does not map Customer.Id:
15+
Mapper.Map(customerDto).Over(customer);
16+
17+
// Save the changes - no problems!
18+
await dbContext.SaveChangesAsync();
19+
```
20+
21+
There are circumstances where you might want to map entity keys, though. A typical case might be to [delete an entity by id](https://stackoverflow.com/questions/2471433/how-to-delete-an-object-by-id-with-entity-framework):
22+
23+
```cs
24+
// Create a dummy Customer entity from the DTO:
25+
var customerToDelete = Mapper.Map(customerDto).ToANew<Customer>();
26+
27+
// Attach then remove the Customer from the context:
28+
dbContext.Customers.Attach(customer);
29+
dbContext.Customers.Remove(customer);
30+
31+
// Save the changes - no Customer.Id, so does not work!
32+
await dbContext.SaveChangesAsync();
33+
```
34+
35+
### Mapping Keys
36+
37+
There's a number of options to change entity key mapping behaviour, depending on your needs.
38+
39+
To map keys by default **in all mappings**, use:
40+
41+
```cs
42+
Mapper.WhenMapping.MapEntityKeys();
43+
44+
// - - - - - - - - - - - - - - -
45+
46+
// Customer.Id will now be mapped:
47+
var customerToDelete = Mapper.Map(customerDto).ToANew<Customer>();
48+
```
49+
50+
To map keys by default when mapping **between two particular types**, use:
51+
52+
```cs
53+
Mapper.WhenMapping
54+
.From<CustomerDto>() // Apply to CustomerDto mappings
55+
.ToANew<Customer>() // Apply to Customer creations
56+
.MapEntityKeys(); // Map entity keys
57+
58+
// - - - - - - - - - - - - - - -
59+
60+
// Customer.Id will now be mapped:
61+
var customerToDelete = Mapper.Map(customerDto).ToANew<Customer>();
62+
```
63+
64+
To map keys for an **individual mapping**, use:
65+
66+
```cs
67+
// Map the DTO, including to Customer.Id:
68+
var customerToDelete = Mapper
69+
.Map(customerDto)
70+
.ToANew<Customer>(cfg => cfg.MapEntityKeys());
71+
```
72+
73+
## Opting Out
74+
75+
If the default behaviour is changed to map keys, key mapping can be disabled when necessary.
76+
77+
To ignore keys when mapping **between two particular types**, use:
78+
79+
```cs
80+
// Map keys by default:
81+
Mapper.WhenMapping.MapEntityKeys();
82+
83+
// Ignore entity keys when mapping from any
84+
// source Type to a Customer:
85+
Mapper.WhenMapping
86+
.To<Customer>() // Apply to Customer mappings
87+
.IgnoreEntityKeys(); // Do not map entity keys
88+
```
89+
90+
To ignore keys for an **individual mapping**, use:
91+
92+
```cs
93+
// Map keys by default:
94+
Mapper.WhenMapping.MapEntityKeys();
95+
96+
// - - - - - - - - - - - - - - -
97+
98+
// Ignore entity keys for this mapping:
99+
Mapper
100+
.Map(customerDto)
101+
.Over(customer, cfg => cfg.IgnoreEntityKeys());
102+
```

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ nav:
4545
- Dependency injection: configuration/Dependency-Injection.md
4646
- Member values: configuration/Member-Values.md
4747
- Constructor arguments: configuration/Constructor-Arguments.md
48+
- Entity mapping: configuration/Entity-Mapping.md
4849
- Member name patterns: configuration/Member-Name-Patterns.md
4950
- To-string formatting: configuration/To-String-Formatting.md
5051
- Enum pairing: Enum-Mapping/#configuring-enum-pairs

0 commit comments

Comments
 (0)