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(); } }
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); }
/// <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); }
// CRUD operations public Product Create(Product product) { using (var t = session.BeginTransaction()) { session.Save(product); t.Commit(); return(product); } }
/// <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))); } }