private void AssertGenericListMatches(IEnumerable actualEnumerable, IEnumerable <TListElement> expectedEnumerable) { if (actualEnumerable == null) { throw new ArgumentNullException("actualEnumerable", "Actual and expected are not equal (actual was null)."); } if (expectedEnumerable == null) { throw new ArgumentNullException("expectedEnumerable", "Actual and expected are not equal (expected was null)."); } var actualList = actualEnumerable.Cast <object>().ToList(); var expectedList = expectedEnumerable.ToList(); if (actualList.Count != expectedList.Count) { throw new ApplicationException(String.Format("Actual count ({0}) does not equal expected count ({1})", actualList.Count, expectedList.Count)); } var equalsFunc = (EntityEqualityComparer != null) ? new Func <object, object, bool>((a, b) => EntityEqualityComparer.Equals(a, b)) : new Func <object, object, bool>(Equals); var result = actualList.FirstOrDefault(item => actualList.Count(x => equalsFunc(item, x)) != expectedList.Count(x => equalsFunc(item, x))); if (result != null) { throw new ApplicationException(String.Format("Actual count of item {0} ({1}) does not equal expected item count ({2})", result, actualList.Count(x => x == result), expectedList.Count(x => (object)x == result))); } }
public void UserCanBeComparedWithEntityComparer() { IEqualityComparer<User> entityComparer = new EntityEqualityComparer(); var user1 = new User(); var user2 = new User(); entityComparer.Equals(user1, user2) .Should().BeFalse(); }
public void UserCanBeComparedWithEntityComparer() { IEqualityComparer <User> entityComparer = new EntityEqualityComparer(); var user1 = new User(); var user2 = new User(); entityComparer.Equals(user1, user2) .Should().BeFalse(); }
public T Update <T>(T entity) where T : class { var entry = DbContext.Entry(entity); if (entry == null) { return(null); } var dbSet = Table <T>(); if (entry.State == EntityState.Detached) { var comparer = new EntityEqualityComparer <T>(this); var hash = comparer.GetHashCode(entity); var attachedEntity = dbSet.Local.FirstOrDefault(e => comparer.GetHashCode(e) == hash); if (attachedEntity != null) { // Update only root attributes for lazy loaded entities if (DbContext.Configuration.LazyLoadingEnabled || !_options.MergeOnUpdate) { var attachedEntry = DbContext.Entry(attachedEntity); attachedEntry.CurrentValues.SetValues(entity); entry = attachedEntry; } else { Merge(entity, attachedEntity, null); entry = DbContext.Entry(attachedEntity); } } else { dbSet.Attach(entity); entry.State = EntityState.Modified; } } else { entry.State = EntityState.Modified; } if (_options.CommitOnCrud) { DbContext?.SaveChanges(); } return(entry.Entity); }
private void AssertGenericListMatches(IEnumerable actualEnumerable, IEnumerable <TListElement> expectedEnumerable) { if (actualEnumerable == null) { throw new ArgumentNullException("actualEnumerable", "Actual and expected are not equal (actual was null)."); } if (expectedEnumerable == null) { throw new ArgumentNullException("expectedEnumerable", "Actual and expected are not equal (expected was null)."); } List <object> actualList = new List <object>(); foreach (var item in actualEnumerable) { actualList.Add(item); } var expectedList = expectedEnumerable.ToList(); if (actualList.Count != expectedList.Count) { throw new ApplicationException("Actual count does not equal expected count"); } var equalsFunc = (EntityEqualityComparer != null) ? new Func <object, object, bool>((a, b) => EntityEqualityComparer.Equals(a, b)) : new Func <object, object, bool>(Equals); for (var i = 0; i < actualList.Count; i++) { if (equalsFunc(actualList[i], expectedList[i])) { continue; } var message = String.Format("Expected '{0}' but got '{1}' at position {2}", expectedList[i], actualList[i], i); throw new ApplicationException(message); } }
static void Main(string[] args) { // More specific = less specific type IEqualityComparer <User> entityComparer = new EntityEqualityComparer(); var areEqual = entityComparer.Equals(user1, user2); Console.WriteLine($"user1 {(areEqual ? "==" : "!=")} user2"); var user1ref = user1; areEqual = entityComparer.Equals(user1ref, user1); Console.WriteLine($"user1ref {(areEqual ? "==" : "!=")} user1"); Entity entity1ref = user1; // Downcast areEqual = (entityComparer as IEqualityComparer <Entity>).Equals(entity1ref, user1); Console.WriteLine($"entity1ref {(areEqual ? "==" : "!=")} user1"); }
static void Main(string[] args) { IEntityRepository <Entity> entityRepository = new EntityRepository(); IEntityRepository <Entity> userRepository = new UserRepository(); IEqualityComparer <User> entityComparer = new EntityEqualityComparer(); var user1 = new User(); var user2 = new User(); var result = entityComparer.Equals(user1, user2); if (result) { Console.WriteLine("ERROR"); } Console.ReadLine(); }
private void Merge(object source, object target, IReadOnlyCollection <string[]> paths) { var context = DbContext; var comparer = new EntityEqualityComparer(this); var autoDetectChangesEnabled = context.Configuration.AutoDetectChangesEnabled; try { context.Configuration.AutoDetectChangesEnabled = false; context.Entry(target).CurrentValues.SetValues(source); MergeImplementation(context, source, target, comparer, null, paths, 0); context.ChangeTracker.DetectChanges(); } finally { context.Configuration.AutoDetectChangesEnabled = autoDetectChangesEnabled; } }
public async Task UpdateRangeAsync <TEntity>(IEnumerable <TEntity> items) where TEntity : class, IId <long>, new() { var entityEqualityComparer = new EntityEqualityComparer(); // entries that are already being tracked var existingEntries = Context.ChangeTracker .Entries <TEntity>().Select(x => x.Entity) .Intersect(items, entityEqualityComparer); // entities that are not tracked var others = items.Except(existingEntries, entityEqualityComparer); // update entities that are not being tracked Context.UpdateRange(others); await Context.SaveChangesAsync(); }
public Dictionary <MembershipUser, int> GetAllTimePointsNegative(int?amountToTake) { var comparer = new EntityEqualityComparer <MembershipUser>(); amountToTake = amountToTake ?? int.MaxValue; var points = _context.MembershipUserPoints.AsNoTracking() .Include(x => x.User).ToList(); return(points.GroupBy(x => x.User, comparer) .Select(x => new { User = x.Key, Points = x.Select(p => p.Points).Sum() }) .OrderBy(x => x.Points) .Take((int)amountToTake) .ToDictionary(x => x.User, x => x.Points)); }
public async Task DeleteRangeAsync <TEntity>(IEnumerable <TEntity> items) where TEntity : class, IId <long>, new() { bool originalAutoDetectChangesEnabled = Context .ChangeTracker.AutoDetectChangesEnabled; // set false, because ChangeTracker.Entries would be ineffective otherwise Context.ChangeTracker.AutoDetectChangesEnabled = false; try { var existingItems = Context.ChangeTracker.Entries <TEntity>().Select(x => x.Entity); var entityEqualityComparer = new EntityEqualityComparer(); // entries that are being tracked (must delete the tracked object) var trackedItemsToDelete = existingItems.Intersect(items, entityEqualityComparer) .ToList(); // entities that are not tracked var otherItems = items.Except(existingItems, entityEqualityComparer) .ToList(); Context.RemoveRange(trackedItemsToDelete); Context.RemoveRange(otherItems); await Context.SaveChangesAsync(); } finally { // set to previous value (usually true, because we want to detect changes for updates to be more effective and update only some properties) Context.ChangeTracker.AutoDetectChangesEnabled = originalAutoDetectChangesEnabled; } }
/// <summary> /// Return an optional amount of points from the current year, returned ordered by amount of points per user /// </summary> /// <param name="amountToTake"></param> /// <returns></returns> public Dictionary <MembershipUser, int> GetThisYearsPoints(int?amountToTake) { var comparer = new EntityEqualityComparer <MembershipUser>(); amountToTake = amountToTake ?? int.MaxValue; var thisYear = DateTime.UtcNow.Year; // We tolist here as GroupBy is expensive operation on the DB with EF var points = _context.MembershipUserPoints.AsNoTracking() .Include(x => x.User) .Where(x => x.DateAdded.Year == thisYear) .ToList(); return(points.GroupBy(x => x.User, comparer) .Select(x => new { User = x.Key, Points = x.Select(p => p.Points).Sum() }) .OrderByDescending(x => x.Points) .Take((int)amountToTake) .ToDictionary(x => x.User, x => x.Points)); }
/// <summary> /// Return an optional amount of points from the current week, returned ordered by amount of points per user /// </summary> /// <param name="amountToTake"></param> /// <returns></returns> public Dictionary <MembershipUser, int> GetCurrentWeeksPoints(int?amountToTake) { var comparer = new EntityEqualityComparer <MembershipUser>(); amountToTake = amountToTake ?? int.MaxValue; var date = DateTime.UtcNow; var start = date.Date.AddDays(-(int)date.DayOfWeek); var end = start.AddDays(7); // We tolist here as GroupBy is expensive operation on the DB with EF var points = _context.MembershipUserPoints.AsNoTracking() .Include(x => x.User) .Where(x => x.DateAdded >= start && x.DateAdded < end).ToList(); return(points.GroupBy(x => x.User, comparer) .Select(x => new { User = x.Key, Points = x.Select(p => p.Points).Sum() }) .OrderByDescending(x => x.Points) .Take((int)amountToTake) .ToDictionary(x => x.User, x => x.Points)); }
private static IEqualityComparer <TEntity> Create <TEntity, TId>(ref IEqualityComparer <TEntity> field) where TEntity : IEntity <TId> where TId : IEquatable <TId> { return(field = new EntityEqualityComparer <TEntity, TId>()); }