Guest User

Untitled

a guest
May 25th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.48 KB | None | 0 0
  1. var post = await dbContext.Posts
  2. .SingleOrDefaultAsync(someId);
  3.  
  4. post.PostCategories = ... Some new collection...; // <<<
  5. dbContext.Posts.Update(post);
  6. await dbContext.SaveChangesAsync();
  7.  
  8. public static class EFCoreExtensions
  9. {
  10. public static void UpdateLinks<TLink, TFromId, TToId>(this DbSet<TLink> dbSet,
  11. Expression<Func<TLink, TFromId>> fromIdProperty, TFromId fromId,
  12. Expression<Func<TLink, TToId>> toIdProperty, IEnumerable<TToId> toIds)
  13. where TLink : class, new()
  14. {
  15. // link => link.FromId == fromId
  16. Expression<Func<TFromId>> fromIdVar = () => fromId;
  17. var filter = Expression.Lambda<Func<TLink, bool>>(
  18. Expression.Equal(fromIdProperty.Body, fromIdVar.Body),
  19. fromIdProperty.Parameters);
  20. var existingLinks = dbSet.AsTracking().Where(filter);
  21.  
  22. var toIdSet = new HashSet<TToId>(toIds);
  23. if (toIdSet.Count == 0)
  24. {
  25. //The new set is empty - delete all existing links
  26. dbSet.RemoveRange(existingLinks);
  27. return;
  28. }
  29.  
  30. // Delete the existing links which do not exist in the new set
  31. var toIdSelector = toIdProperty.Compile();
  32. foreach (var existingLink in existingLinks)
  33. {
  34. if (!toIdSet.Remove(toIdSelector(existingLink)))
  35. dbSet.Remove(existingLink);
  36. }
  37.  
  38. // Create new links for the remaining items in the new set
  39. if (toIdSet.Count == 0) return;
  40. // toId => new TLink { FromId = fromId, ToId = toId }
  41. var toIdParam = Expression.Parameter(typeof(TToId), "toId");
  42. var createLink = Expression.Lambda<Func<TToId, TLink>>(
  43. Expression.MemberInit(
  44. Expression.New(typeof(TLink)),
  45. Expression.Bind(((MemberExpression)fromIdProperty.Body).Member, fromIdVar.Body),
  46. Expression.Bind(((MemberExpression)toIdProperty.Body).Member, toIdParam)),
  47. toIdParam);
  48. dbSet.AddRange(toIdSet.Select(createLink.Compile()));
  49. }
  50. }
  51.  
  52. var post = await dbContext.Posts
  53. .SingleOrDefaultAsync(someId);
  54.  
  55. dbContext.Set<PostCategory>().UpdateLinks(pc =>
  56. pc.PostId, post.Id, pc => pc.CategoryId, postCategories.Select(pc => pc.CategoryId));
  57.  
  58. await dbContext.SaveChangesAsync();
  59.  
  60. dbContext.Set<PostCategory>().UpdateLinks(pc =>
  61. pc.PostId, post.Id, pc => pc.CategoryId, postCategoryIds);
  62.  
  63. dbContext.Set<PostCategory>().UpdateLinks(pc =>
  64. pc.PostId, post.Id, pc => pc.CategoryId, postCategories.Select(c => c.Id));
Add Comment
Please, Sign In to add comment