public void UpdateManyToMany_NoExisting_AddedElements()
        {
            using (var transaction = connection.BeginTransaction())
            {
                parent = new ParentClass();
                connection.Save(parent);

                var newChildren = new[] { new ChildDto {
                                              Test = "First"
                                          }, new ChildDto {
                                              Test = "Second"
                                          } };
                connection.UpdateManyToMany(parent, parent.Children, newChildren, mapper);

                connection.Cache.Clear();

                var newParent = connection.Load <ParentClass>(parent.Id);

                Assert.Equal(2, newParent.Children.Count);
                var children = newParent.Children;
                Assert.True(children.Any(c => c.Child.Test == "First"));
                Assert.True(children.Any(c => c.Child.Test == "Second"));
                transaction.Rollback();
            }
        }
예제 #2
0
        public static IReadOnlyList <T> UpdateManyToMany <T, TParent, TChild, TChildDto>(this IFolkeConnection connection, TParent parent, IReadOnlyList <T> currentValues, ICollection <TChildDto> newDtos, IManyToManyHelperConfiguration <TChild, TChildDto> helper)
            where T : class, IManyToManyTable <TParent, TChild>, new()
            where TParent : IFolkeTable
            where TChild : class, IFolkeTable, new()
        {
            if (newDtos == null)
            {
                newDtos = new List <TChildDto>();
            }

            // Looking for any value in newDtos that is not in currentValues
            var valuesToAdd = newDtos.Where(v => currentValues == null || !currentValues.Any(cv => helper.AreEqual(cv.Child, v))).ToList();
            var newValues   = currentValues?.ToList() ?? new List <T>();

            if (valuesToAdd.Any())
            {
                // Query from the database the values that needs to be added to the parent
                var existingChildren = helper.QueryExisting(connection, valuesToAdd);

                foreach (var newDto in valuesToAdd)
                {
                    var child = existingChildren?.SingleOrDefault(c => helper.AreEqual(c, newDto));
                    if (child == null)
                    {
                        // If the element to add does not exist in the database, create it (may fail if helper.Map/helper.UpdateDto is not implemented because one does not want to allow that)
                        child = helper.Map(newDto);
                        connection.Save(child);
                        helper.UpdateDto(newDto, child);
                    }

                    // Create a new parent-child link with this value
                    var newElement = new T {
                        Child = child, Parent = parent
                    };
                    connection.Save(newElement);
                    newValues.Add(newElement);
                }
            }

            if (currentValues != null)
            {
                // Look for values to remove
                var valuesToRemove = currentValues.Where(cv => newDtos.All(nv => !helper.AreEqual(cv.Child, nv))).ToArray();
                if (valuesToRemove.Any())
                {
                    connection.Delete <T>().From().Where(c => c.Id.In(valuesToRemove.Select(s => s.Id))).Execute();
                    foreach (var value in valuesToRemove)
                    {
                        newValues.Remove(value);
                    }
                }
            }
            return(newValues);
        }
예제 #3
0
        /// <summary>
        /// Updates a collection of items from a collection of item views. Existing items are updated or deleted. New items are added.
        /// </summary>
        /// <typeparam name="TChild">The database item</typeparam>
        /// <typeparam name="TChildView">A view of this database item. Matching items have same Id</typeparam>
        /// <param name="connection">The database connection</param>
        /// <param name="currentValues">The current value from the database</param>
        /// <param name="newValues">The new values</param>
        /// <param name="factory">A factory that create a new item</param>
        /// <param name="updater">A delegate that updates an existing item</param>
        public static List <TChild> UpdateCollectionFromViews <TChild, TChildView>(this IFolkeConnection connection, IReadOnlyCollection <TChild> currentValues, IReadOnlyCollection <TChildView> newValues,
                                                                                   Func <TChildView, TChild> factory, Func <TChildView, TChild, bool> updater)
            where TChild : class, IFolkeTable, new()
            where TChildView : class, IFolkeTable, new()
        {
            var ret = new List <TChild>();

            if (currentValues == null || !currentValues.Any())
            {
                foreach (var childValue in newValues)
                {
                    var child = factory(childValue);
                    ret.Add(child);
                    connection.Save(child);
                }
                return(ret);
            }

            var newValueToAdd = newValues.Where(x => currentValues.All(y => y.Id != x.Id));

            foreach (var currentValue in currentValues)
            {
                var newValue = newValues.FirstOrDefault(x => x.Id == currentValue.Id);
                if (newValue == null)
                {
                    connection.Delete(currentValue);
                }
                else
                {
                    if (updater != null && updater(newValue, currentValue))
                    {
                        connection.Update(currentValue);
                    }
                    ret.Add(currentValue);
                }
            }

            foreach (var childDto in newValueToAdd)
            {
                var child = factory(childDto);
                ret.Add(child);
                connection.Save(child);
            }
            return(ret);
        }
예제 #4
0
 // CRUD operations
 public Product Create(Product product)
 {
     using (var t = session.BeginTransaction())
     {
         session.Save(product);
         t.Commit();
         return(product);
     }
 }
예제 #5
0
        /// <summary>
        /// Update a collection of items using a collection of values. These values don't have an id to identity them, so a areEqual delegate
        /// must be given as a parameter. Existing items that is not in newValues are deleted.
        /// </summary>
        /// <typeparam name="TChild">The database item type</typeparam>
        /// <typeparam name="TChildView">The view type</typeparam>
        /// <param name="connection">The database connection</param>
        /// <param name="currentValues">The current value from the database</param>
        /// <param name="newValues">The new values</param>
        /// <param name="areEqual">Must return true if the two values are equal</param>
        /// <param name="factory">Create a new item</param>
        public static List <TChild> UpdateCollectionFromValues <TChild, TChildView>(this IFolkeConnection connection, IReadOnlyCollection <TChild> currentValues, IReadOnlyCollection <TChildView> newValues,
                                                                                    Func <TChildView, TChild> factory, Func <TChildView, TChild, bool> areEqual)
            where TChild : class, IFolkeTable, new()
        {
            var ret = new List <TChild>();

            if (currentValues == null || !currentValues.Any())
            {
                foreach (var childValue in newValues)
                {
                    var child = factory(childValue);
                    connection.Save(child);
                    ret.Add(child);
                }
                return(ret);
            }

            var newValueToAdd = newValues.Where(x => currentValues.All(y => !areEqual(x, y)));

            foreach (var currentValue in currentValues)
            {
                if (!newValues.Any(x => areEqual(x, currentValue)))
                {
                    connection.Delete(currentValue);
                }
                else
                {
                    ret.Add(currentValue);
                }
            }

            foreach (var childDto in newValueToAdd)
            {
                var child = factory(childDto);
                connection.Save(child);
                ret.Add(child);
            }
            return(ret);
        }
        public async Task <IHttpActionResult <PrivateMessageView <TUserView> > > Post([FromBody] PrivateMessageView <TUserView> value)
        {
            var account = await accountService.GetCurrentUserAsync();

            if (account == null)
            {
                return(Unauthorized <PrivateMessageView <TUserView> >());
            }
            if (value.AccountRecipients.Count == 0)
            {
                return(BadRequest <PrivateMessageView <TUserView> >("Aucun destinataire"));
            }
            using (var transaction = session.BeginTransaction())
            {
                var recipientAccounts = await accountService.GetUsersAsync(value.AccountRecipients);

                var html = await htmlSanitizerService.Sanitize(value.Text, account);

                var privateMessage = new PrivateMessage <TUser>
                {
                    Author = account,
                    Text   = html,
                    Title  = value.Title
                };

                session.Save(privateMessage);

                var recipients = new List <PrivateMessageRecipient <TUser> >();

                foreach (var recipientAccount in recipientAccounts)
                {
                    var recipient = new PrivateMessageRecipient <TUser>
                    {
                        PrivateMessage = privateMessage,
                        Recipient      = recipientAccount
                    };
                    recipients.Add(recipient);
                    await session.SaveAsync(recipient);
                }
                privateMessage.Recipients = recipients;
                transaction.Commit();
                return(Created("GetPrivateMessage", value.Id, forumsDataMapping.ToPrivateMessageView(privateMessage)));
            }
        }