Esempio n. 1
0
        /// <summary>
        /// Updates a collection, adding/removing values. The entities in the collection are assumed to be attached/tracked.
        /// newValues need not already exist.
        /// Also updates the fields of each element.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collection"></param>
        /// <param name="newValues"></param>
        /// <param name="context"></param>
        public static void UpdateCollectionAndElements <T>(this ICollection <T> collection, IEnumerable <T> newValues, IMyDbContext context) where T : class, IEntity
        {
            //remove those that need to be removed
            var toRemove = collection.Where(x => !newValues.Any(y => y.ID == x.ID)).ToList();

            foreach (T item in toRemove)
            {
                context.SetEntryState(item, EntityState.Deleted);
            }

            //find the ones that overlap and add or update them
            foreach (T item in newValues)
            {
                if (item.ID == 0) //this means it's newly added
                {
                    collection.Add(item);
                }
                else //this is an existing entity, update it
                {
                    var attached = collection.FirstOrDefault(x => x.ID == item.ID); //no need for Entry()/Attach() -  these are already in the ObjectStateManager
                    if (attached == null)
                    {
                        continue;                   //if the collection on the server has been changed and the client tries to update a deleted element, you can end up in this scenario...just skip it
                    }
                    context.UpdateEntryValues(attached, item);
                }
            }
        }