public void ShouldReturnNothingIfSearchingForDetached()
        {
            CollectionChangeDetector <int> detector = new CollectionChangeDetector <int>();
            var changes = detector.GetChanges(new int[] { 1 }, new int[0], ElementState.Detached);

            Assert.AreEqual(0, changes.Count, "There should have only been one change.");
        }
 public void ShouldDetectItemsUnmodified()
 {
     CollectionChangeDetector<int> detector = new CollectionChangeDetector<int>();
     var changes = detector.GetChanges(new int[] { 1 }, new int[] { 1 }, ElementState.Unmodified);
     Assert.AreEqual(1, changes.Count, "There should have only been one change.");
     var change = changes.Single();
     Assert.AreEqual(1, change.Item, "The wrong item was returned.");
     Assert.AreEqual(ElementState.Unmodified, change.State, "The item should have been unmodified.");
 }
        public void ShouldDetectItemsUnmodified()
        {
            CollectionChangeDetector <int> detector = new CollectionChangeDetector <int>();
            var changes = detector.GetChanges(new int[] { 1 }, new int[] { 1 }, ElementState.Unmodified);

            Assert.AreEqual(1, changes.Count, "There should have only been one change.");
            var change = changes.Single();

            Assert.AreEqual(1, change.Item, "The wrong item was returned.");
            Assert.AreEqual(ElementState.Unmodified, change.State, "The item should have been unmodified.");
        }
        public async Task <T> SaveGraph <TItems>(T live, string itemsPropertyName)
            where TItems : class, IIdentity <TItems>
        {
            var itemsPropertyInfo = typeof(T).GetProperty(itemsPropertyName);

            if (itemsPropertyInfo == null)
            {
                bool isInvalid = !itemsPropertyInfo.PropertyType.GetInterfaces().Any(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable <TItems>));

                var    tPropertyName = typeof(T).Name;
                string message       = $"SaveGraph({tPropertyName} live, {itemsPropertyName}): there is no {itemsPropertyName} collection property on {tPropertyName} type.";

                throw new ApplicationException(message);
            }

            try
            {
                if (live != null)
                {
                    if (live.Id != 0)                                                                                           //updating entity
                    {
                        T store = await context.Set <T>().Include(itemsPropertyName).FirstOrDefaultAsync(c => c.Id == live.Id); //find the store entity

                        if (!store.Equals(live))                                                                                //if store and live entity is not the same then update the store entity to the live entity
                        {
                            store.UpdatePropertiesFrom(live);                                                                   //using the custom UpdatePropertiesFrom method
                        }

                        IList <TItems> liveItems  = itemsPropertyInfo.GetValue(live) as IList <TItems>,                 //obtian the collection items using reflection
                                       storeItems = itemsPropertyInfo.GetValue(store) as IList <TItems>;                //for live and store

                        var itemsChanges = CollectionChangeDetector <TItems> .CollectionChanges(liveItems, storeItems); //get the collection changes for the items

                        itemsChanges.Added.ForEach(liveItem =>                                                          //items to be added
                        {
                            storeItems.Add(liveItem);                                                                   //add them to the store items
                        });

                        itemsChanges.Deleted.ForEach(liveItem =>                                        //items to be deleted
                        {
                            TItems storeItem = storeItems.First(sci => sci.Id == liveItem.Id);          //find the corresponding store item

                            context.Set <TItems>().Remove(storeItem);                                   //remove them from the context ( removing from the store item would not work )
                        });

                        itemsChanges.Updated.ForEach(liveItem =>                                        //items to be updated
                        {
                            TItems storeItem = storeItems.First(sci => sci.Id == liveItem.Id);          //find the corresponding store item

                            storeItem.UpdatePropertiesFrom(liveItem);                                   //update the store
                        });
                    }
                    else
                    {                                                                                   //adding the live entity
                        context.Set <T>().Add(live);
                    }

                    await context.SaveChangesAsync();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return(live);
        }
 public void ShouldReturnNothingIfSearchingForDetached()
 {
     CollectionChangeDetector<int> detector = new CollectionChangeDetector<int>();
     var changes = detector.GetChanges(new int[] { 1 }, new int[0], ElementState.Detached);
     Assert.AreEqual(0, changes.Count, "There should have only been one change.");
 }