static void Main(string[] args) { DifferenceController differenceController = new DifferenceController(); differenceController.CustomBuilder <People>() .One(x => x.Phone) .All(x => x.SweetHome) //.GoDepth(x => x.SweetHome) .Build(); differenceController.AutoBuilder <People>() .Stop(x => x.SweetHome) .Build(); People p1 = new People { Id = 1, FullName = "Andy", BirdthDay = DateTime.Today, Phone = "88005553535", SweetHome = new Home { Id = 111, IsPrivate = true } }; People p2 = new People { Id = 21, FullName = "Greogre", BirdthDay = DateTime.MinValue, Phone = "900", SweetHome = new Home { Id = 222, IsPrivate = true, Address = "ulitsa Pushkina, dom Kolotushkina, 47", RoomNumber = 1234, Square = 120, Floor = 34, } }; var differences = differenceController.GetCustomDifferences(p1, p2); var differences2 = differenceController.GetAutoDifferences(p1, p2); var differences3 = differenceController.GetAutoDifferences(p1.SweetHome, p2.SweetHome); Console.WriteLine("Hello World!"); }
public async Task AddOrUpdateAsync(IEnumerable <ApartmentInfo> data) { var newEntitiesMap = data.Select(x => x.ToEntity()) .DistinctBy(x => x.ExternalId) .ToDictionary(x => x.ExternalId, x => x); using var uow = new UnitOfWork(_contextProvider.Create()); var existsApartmentsMap = (await uow.Apartments .GetAsync(x => newEntitiesMap.Keys.Contains(x.ExternalId))) .ToDictionary(x => x.ExternalId, x => x); // Сохраняем новые объявления. var newItems = newEntitiesMap.Values.Where(x => !existsApartmentsMap.Keys.Contains(x.ExternalId)).ToArray(); _logger.Trace($"{GetType().Name}: Всего на запись отправлено: {newEntitiesMap.Count};" + $" уже существует в БД: {existsApartmentsMap.Count}; из них новых записей: {newItems.Length}"); await uow.Apartments.AddAsync(newItems); await uow.SaveChangesAsync(); if (newItems.Length > 0) { _logger.Trace($"{GetType().Name}: Было успешно добавлено {newItems.Length} объявлений в БД:" + $"\n* {string.Join("\n* ", newItems.Select(x => $"[{x.Id}] {x.Title} за {x.Price}руб."))}"); } // Теперь пишем историю для всех объявлений. var apartmentsChanges = new List <ItemChangeEntity>(); var updatedApartments = new List <ApartmentEntity>(existsApartmentsMap.Count); foreach (var oldApartment in existsApartmentsMap.Values) { // Если объявления нету в списке новых - значит оно устарело и исчезло. if (!newEntitiesMap.TryGetValue(oldApartment.ExternalId, out var newApartment)) { continue; } // Если не было изменений, то элемент нас не интересует. var diffs = _differenceController.GetAutoDifferences(oldApartment, newApartment); if (diffs.Length == 0) { continue; } _logger.Trace($"{GetType().Name}: Объявление с Id == {oldApartment.Id} (ExternalId == {oldApartment.ExternalId}) имеет {diffs.Length} изменений"); // Сохраняем изменения объекта. apartmentsChanges.AddRange(diffs.Select(diff => new ItemChangeEntity { Table = ApartmentEntity.TableName, ObjectId = oldApartment.Id, PropertyName = diff.PropertyName, PropertyTypeFullName = diff.PropertyType.FullName, OldValueJson = JsonConvert.SerializeObject(diff.ValueLeft), NewValueJson = JsonConvert.SerializeObject(diff.ValueRight) })); // Сохраянем результат. newApartment.Id = oldApartment.Id; updatedApartments.Add(newApartment); } await uow.Apartments.UpdateAsync(updatedApartments); await uow.ItemsChanges.AddAsync(apartmentsChanges); await uow.SaveChangesAsync(); _logger.Trace($"{GetType().Name}: Всего было изменено {updatedApartments.Count} апартаметов и {apartmentsChanges.Count} полей"); if (apartmentsChanges.Count > 0) { _logger.Trace($"{GetType().Name}: Были изменены поля у некоторых объявлений:" + $"\n* {string.Join("\n* ", apartmentsChanges.Select(x => $"[Id {x.ObjectId}] {x.PropertyName}: {x.OldValueJson} ==> {x.NewValueJson}"))}"); } await TraceApartmentsChanges(uow, newItems, updatedApartments); }