问题
Say you have the following Contact DTO. Address/PhoneNumber/EmailAddress/WebSiteAddress classes are simple DTOs as well (just data no behavior)
public class Contact
{
public Address[] Addresses { get; set; }
public PhoneNumber[] PhoneNumbers { get; set; }
public EmailAddress[] EmailAddresses { get; set; }
public WebSiteAddress[] WebSiteAddresses { get; set; }
}
How should I model DTOs to allow implementing the following behavior?
The client can submit a request that will
- add a phone number, update two phone numbers and delete two add two
- add two email addresses, update one email address and delete three
add three website addresses, update two website addresses and delete two. You get the idea.
One option is to add an Action attribute to each Address / PhoneNumber / EmailAddress / WebSiteAddress.
Then the code the update addresses look like this:
var addressesToUpdate = serviceContact.Addresses.Where(x => x.AddressAction.ToUpper() == "UPDATE");
var addressesToAdd = serviceContact.Addresses.Where(x => x.AddressAction.ToUpper() == "ADD");
var addressesToDelete = serviceContact.Addresses.Where(x => x.AddressAction.ToUpper() == "DELETE").Select(x => x.AddressId);
Repeating this for all other lists will probably create duplication.
My question is:
How should I model service DTOs with updatable lists while avoiding duplication?
回答1:
Generally I'll try to keep my writes idempotent which means it should have the same side-effect (i.e. end result) of calling it when you have no records or all records (i.e. Store or Update).
Basically this means that the client sends the complete state: i.e.
- What entries don't exist => gets created,
- The entities that already exist => get updated,
- Whilst the entities that aren't in the request DTO => get deleted.
OrmLite's db.Save()
command has nice support for this where it detects if a record(s) already exist and will issue an UPDATE otherwise will INSERT.
回答2:
You can use ETags with conditional requests instead of providing the complete state. Use the ETag as a version of the list and change it each time the list changes. On the client side, use the ETag to request an update using the If-None-Match http header and be prepared to receive a 402 Precondition Failed status if the list changed while the request was sent.
来源:https://stackoverflow.com/questions/12283839/modeling-editable-lists-in-dtos-used-by-services