Example #1
0
        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);
        }