Created
November 20, 2019 17:40
-
-
Save jasoncable/cadc8c81717a66bd7fed580b86bb9722 to your computer and use it in GitHub Desktop.
C# - DTO to Entity Comparison that outputs items to add/delete/update to/from/in target collection
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Let's say you have a list of DTOs (data tranfer objects) that someone | |
// posted on the web or anywhere. Items have been removed and added to it. | |
// You need to compare the input with what exists in the database | |
// and find out 1.) new items to add to the database, | |
// 2.) items to delete from the database, and | |
// 3.) items to update in the database. | |
// You don't want to continually rewrite that sort of thing over and over again, like I have. | |
// The problem with conventional methods is that the data types on either side of the | |
// equation are probably different types. | |
// The following will produce the items to add/delete/update by comparing them via | |
// a user-defined comparison Func<T,U,bool>. | |
// | |
// This sample assumes a list of ThingDto objects that are posted from the web | |
// and using EntityFramework, we compare what is in the database versus what | |
// is coming in from the web. | |
DbContext context = new DbContext(); // pretend EntityFramework // context.Things is of type ThingEntity | |
List<ThingDto> listPostedFromWeb;// passed in parameter | |
Func<ThingDto, ThingEntity, bool> comparer = (compDto, compEntity) => | |
{ | |
// what comparison between these different types ensures | |
// that they are the same? | |
return compDto.Id == compEntity.id; | |
}; | |
var (insert, update, delete) = GetChanges( | |
listPostedFromWeb ?? new List<ThingDto>(), // list from the web or a new list | |
context.Things.Where(x => x.CategoryId == XYZ), // EntityFramework query | |
comparer); // your custom comparer. | |
public (IEnumerable<L> insert, IEnumerable<R> update, IEnumerable<R> delete) GetChanges<L,R>(IEnumerable<L> models, IEnumerable<R> dos, Func<L,R,bool> comparer) | |
{ | |
IEnumerable<L> itemsToInsert; | |
if (models == null) | |
itemsToInsert = new List<L>(); | |
else if (dos == null) | |
itemsToInsert = models; | |
else | |
itemsToInsert = models.Where(x => !dos.Any(y => comparer(x, y))).ToList(); | |
IEnumerable<R> itemsToUpdate; | |
if (models == null || dos == null) | |
itemsToUpdate = new List<R>(); | |
else | |
itemsToUpdate = dos.Where(x => models.Any(y => comparer(y, x))).ToList(); | |
IEnumerable<R> itemsToDelete; | |
if (models == null) | |
itemsToDelete = dos; | |
else if (dos == null) | |
itemsToDelete = new List<R>(); | |
else | |
itemsToDelete = dos.Where(x => !models.Any(y => comparer(y, x))).ToList(); | |
return (itemsToInsert, itemsToUpdate, itemsToDelete); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment