public async Task SaveCouponsAsync(Coupon[] coupons) { if (coupons.Any(x => x.Code.IsNullOrEmpty())) { throw new InvalidOperationException($"Coupon can't have empty code!"); } var pkMap = new PrimaryKeyResolvingMap(); var changedEntries = new List <GenericChangedEntry <Coupon> >(); using (var repository = _repositoryFactory()) { var existCouponEntities = await repository.GetCouponsByIdsAsync(coupons.Where(x => !x.IsTransient()).Select(x => x.Id).ToArray()); var nonUniqueCouponErrors = await repository.CheckCouponsForUniquenessAsync(coupons.Where(x => x.IsTransient()).ToArray()); if (!nonUniqueCouponErrors.IsNullOrEmpty()) { throw new InvalidOperationException(string.Join(Environment.NewLine, nonUniqueCouponErrors)); } foreach (var coupon in coupons) { var sourceEntity = AbstractTypeFactory <CouponEntity> .TryCreateInstance(); if (sourceEntity != null) { sourceEntity = sourceEntity.FromModel(coupon, pkMap); var targetCouponEntity = existCouponEntities.FirstOrDefault(x => x.Id == coupon.Id); if (targetCouponEntity != null) { changedEntries.Add(new GenericChangedEntry <Coupon>(coupon, sourceEntity.ToModel(AbstractTypeFactory <Coupon> .TryCreateInstance()), EntryState.Modified)); sourceEntity.Patch(targetCouponEntity); } else { changedEntries.Add(new GenericChangedEntry <Coupon>(coupon, EntryState.Added)); repository.Add(sourceEntity); } } } await repository.UnitOfWork.CommitAsync(); pkMap.ResolvePrimaryKeys(); ClearCache(coupons.Select(x => x.PromotionId).ToArray()); await _eventPublisher.Publish(new CouponChangedEvent(changedEntries)); } }
public void SaveCustomerReviews(CustomerReview[] items) { if (items == null) { throw new ArgumentNullException(nameof(items)); } var pkMap = new PrimaryKeyResolvingMap(); using (var repository = _repositoryFactory()) { using (var changeTracker = GetChangeTracker(repository)) { var alreadyExistEntities = repository.GetCustomerReviewsByIds(items.Where(m => !m.IsTransient()).Select(x => x.Id) .ToArray()); foreach (var derivativeContract in items) { if (derivativeContract.Rate < 1 || derivativeContract.Rate > 5) { continue; } var sourceEntity = AbstractTypeFactory <CustomerReviewEntity> .TryCreateInstance() .FromModel(derivativeContract, pkMap); var targetEntity = alreadyExistEntities.FirstOrDefault(x => x.Id == sourceEntity.Id); if (targetEntity != null) { changeTracker.Attach(targetEntity); sourceEntity.Patch(targetEntity); } else { repository.Add(sourceEntity); _averageProductRateService.SaveAverageProductRates(new AverageProductRate { ProductId = sourceEntity.ProductId, AverageRate = sourceEntity.Rate }); } } CommitChanges(repository); pkMap.ResolvePrimaryKeys(); _averageProductRateService.RecountAverageProductRate(); } } }
public virtual void SaveChanges(CustomerOrder[] orders) { var pkMap = new PrimaryKeyResolvingMap(); var changedEntries = new List <GenericChangedEntry <CustomerOrder> >(); using (var repository = RepositoryFactory()) using (var changeTracker = GetChangeTracker(repository)) { var dataExistOrders = repository.GetCustomerOrdersByIds(orders.Where(x => !x.IsTransient()).Select(x => x.Id).ToArray(), CustomerOrderResponseGroup.Full); foreach (var order in orders) { EnsureThatAllOperationsHaveNumber(order); LoadOrderDependencies(order); var originalEntity = dataExistOrders.FirstOrDefault(x => x.Id == order.Id); //Calculate order totals TotalsCalculator.CalculateTotals(order); var modifiedEntity = AbstractTypeFactory <CustomerOrderEntity> .TryCreateInstance() .FromModel(order, pkMap) as CustomerOrderEntity; if (originalEntity != null) { changeTracker.Attach(originalEntity); var oldEntry = (CustomerOrder)originalEntity.ToModel(AbstractTypeFactory <CustomerOrder> .TryCreateInstance()); DynamicPropertyService.LoadDynamicPropertyValues(oldEntry); changedEntries.Add(new GenericChangedEntry <CustomerOrder>(order, oldEntry, EntryState.Modified)); modifiedEntity?.Patch(originalEntity); } else { repository.Add(modifiedEntity); changedEntries.Add(new GenericChangedEntry <CustomerOrder>(order, EntryState.Added)); } } //Raise domain events EventPublisher.Publish(new OrderChangeEvent(changedEntries)); CommitChanges(repository); pkMap.ResolvePrimaryKeys(); } //Save dynamic properties foreach (var order in orders) { DynamicPropertyService.SaveDynamicPropertyValues(order); } //Raise domain events EventPublisher.Publish(new OrderChangedEvent(changedEntries)); }
/// <summary> /// Create or update members in database /// </summary> /// <param name="members"></param> public virtual void SaveChanges(Member[] members) { var pkMap = new PrimaryKeyResolvingMap(); using (var repository = RepositoryFactory()) using (var changeTracker = GetChangeTracker(repository)) { var existingMemberEntities = repository.GetMembersByIds(members.Where(m => !m.IsTransient()).Select(m => m.Id).ToArray()); foreach (var member in members) { var memberEntityType = AbstractTypeFactory <Member> .AllTypeInfos.Where(t => t.MappedType != null && t.IsAssignableTo(member.MemberType)).Select(t => t.MappedType).FirstOrDefault(); if (memberEntityType != null) { var dataSourceMember = AbstractTypeFactory <MemberDataEntity> .TryCreateInstance(memberEntityType.Name); if (dataSourceMember != null) { dataSourceMember.FromModel(member, pkMap); var dataTargetMember = existingMemberEntities.FirstOrDefault(m => m.Id == member.Id); if (dataTargetMember != null) { changeTracker.Attach(dataTargetMember); dataSourceMember.Patch(dataTargetMember); MemberEventventPublisher.Publish(new MemberChangingEvent(EntryState.Modified, member)); } else { repository.Add(dataSourceMember); MemberEventventPublisher.Publish(new MemberChangingEvent(EntryState.Added, member)); } } } } CommitChanges(repository); pkMap.ResolvePrimaryKeys(); } //Save dynamic properties foreach (var member in members) { DynamicPropertyService.SaveDynamicPropertyValues(member); } CommerceService.UpsertSeoForObjects(members.OfType <ISeoSupport>().ToArray()); }
public coreModel.Catalog Create(coreModel.Catalog catalog) { var pkMap = new PrimaryKeyResolvingMap(); var dbCatalog = catalog.ToDataModel(pkMap); coreModel.Catalog retVal = null; using (var repository = base.CatalogRepositoryFactory()) { repository.Add(dbCatalog); CommitChanges(repository); pkMap.ResolvePrimaryKeys(); } retVal = GetById(dbCatalog.Id); return(retVal); }
public void SaveDynamicPropertyValues(IHasDynamicProperties owner) { if (owner == null) { throw new ArgumentNullException(nameof(owner)); } var objectsWithDynamicProperties = owner.GetFlatObjectsListWithInterface <IHasDynamicProperties>().Where(x => !string.IsNullOrEmpty(x.Id) && !x.DynamicProperties.IsNullOrEmpty()); //Ensure what all properties have proper ObjectId and ObjectType properties set foreach (var obj in objectsWithDynamicProperties) { foreach (var prop in obj.DynamicProperties) { prop.ObjectId = obj.Id; prop.ObjectType = GetObjectTypeName(obj); } } var pkMap = new PrimaryKeyResolvingMap(); using (var repository = _repositoryFactory()) using (var changeTracker = GetChangeTracker(repository)) { var objectTypes = objectsWithDynamicProperties.Select(x => GetObjectTypeName(x)).Distinct().ToArray(); //Converting all incoming properties to db entity and group property values of all objects use for that property.objectType and property.name as complex key var modifiedPropertyEntitiesGroup = objectsWithDynamicProperties.SelectMany(x => x.DynamicProperties.Select(dp => AbstractTypeFactory <DynamicPropertyEntity> .TryCreateInstance().FromModel(dp, pkMap))) .GroupBy(x => $"{x.Name}:{x.ObjectType}"); var originalPropertyEntitites = repository.GetObjectDynamicProperties(objectTypes, objectsWithDynamicProperties.Select(x => x.Id).Distinct().ToArray()).ToList(); foreach (var modifiedPropertyEntityGroupItem in modifiedPropertyEntitiesGroup) { var modifiedPropertyObjectValues = modifiedPropertyEntityGroupItem.SelectMany(x => x.ObjectValues) .Where(x => x.GetValue(EnumUtility.SafeParse(x.ValueType, DynamicPropertyValueType.LongText)) != null) .ToList(); //Try to find original property with same complex key var originalEntity = originalPropertyEntitites.FirstOrDefault(x => $"{x.Name}:{x.ObjectType}".EqualsInvariant(modifiedPropertyEntityGroupItem.Key)); if (originalEntity != null) { changeTracker.Attach(originalEntity); //Update only property values var comparer = AnonymousComparer.Create((DynamicPropertyObjectValueEntity x) => $"{x.ObjectId}:{x.ObjectType}:{x.Locale}:{x.GetValue(EnumUtility.SafeParse(x.ValueType, DynamicPropertyValueType.LongText))}"); modifiedPropertyObjectValues.Patch(originalEntity.ObjectValues, comparer, (sourceValue, targetValue) => { }); } } repository.UnitOfWork.Commit(); pkMap.ResolvePrimaryKeys(); } }
public void UpsertSeoForObjects(coreModel.ISeoSupport[] seoSupportObjects) { if (seoSupportObjects == null) { throw new ArgumentNullException(nameof(seoSupportObjects)); } var pkMap = new PrimaryKeyResolvingMap(); foreach (var seoObject in seoSupportObjects.Where(x => x.Id != null)) { var objectType = seoObject.SeoObjectType; using (var repository = _repositoryFactory()) using (var changeTracker = GetChangeTracker(repository)) { if (seoObject.SeoInfos != null) { // Normalize seoInfo foreach (var seoInfo in seoObject.SeoInfos) { if (seoInfo.ObjectId == null) { seoInfo.ObjectId = seoObject.Id; } if (seoInfo.ObjectType == null) { seoInfo.ObjectType = objectType; } } } if (seoObject.SeoInfos != null) { var target = new { SeoInfos = new ObservableCollection <dataModel.SeoUrlKeyword>(repository.GetObjectSeoUrlKeywords(objectType, seoObject.Id)) }; var source = new { SeoInfos = new ObservableCollection <dataModel.SeoUrlKeyword>(seoObject.SeoInfos.Select(x => AbstractTypeFactory <dataModel.SeoUrlKeyword> .TryCreateInstance().FromModel(x, pkMap))) }; changeTracker.Attach(target); var seoComparer = AnonymousComparer.Create((dataModel.SeoUrlKeyword x) => x.Id ?? string.Join(":", x.StoreId, x.ObjectId, x.ObjectType, x.Language)); source.SeoInfos.Patch(target.SeoInfos, seoComparer, (sourceSeoUrlKeyword, targetSeoUrlKeyword) => sourceSeoUrlKeyword.Patch(targetSeoUrlKeyword)); } CommitChanges(repository); pkMap.ResolvePrimaryKeys(); } } }
public virtual void SaveChanges(ShoppingCart[] carts) { var pkMap = new PrimaryKeyResolvingMap(); var changedEvents = new List <CartChangedEvent>(); using (var repository = _repositoryFactory()) using (var changeTracker = GetChangeTracker(repository)) { var dataExistCarts = repository.GetShoppingCartsByIds(carts.Where(x => !x.IsTransient()).Select(x => x.Id).ToArray()); foreach (var cart in carts) { var originalEntity = dataExistCarts.FirstOrDefault(x => x.Id == cart.Id); var originalCart = originalEntity != null?originalEntity.ToModel(AbstractTypeFactory <ShoppingCart> .TryCreateInstance()) : cart; var changingEvent = new CartChangeEvent(originalEntity == null ? EntryState.Added : EntryState.Modified, originalCart, cart); _changingEventPublisher.Publish(changingEvent); changedEvents.Add(new CartChangedEvent(changingEvent.ChangeState, changingEvent.OrigCart, changingEvent.ModifiedCart)); var modifiedEntity = AbstractTypeFactory <ShoppingCartEntity> .TryCreateInstance().FromModel(cart, pkMap); if (originalEntity != null) { changeTracker.Attach(originalEntity); modifiedEntity.Patch(originalEntity); } else { repository.Add(modifiedEntity); } } CommitChanges(repository); pkMap.ResolvePrimaryKeys(); } //Save dynamic properties foreach (var cart in carts) { _dynamicPropertyService.SaveDynamicPropertyValues(cart); } //Raise changed events foreach (var changedEvent in changedEvents) { _changedEventPublisher.Publish(changedEvent); } }
public async Task SaveChangesAsync(IEnumerable <Property> properties) { var pkMap = new PrimaryKeyResolvingMap(); var changedEntries = new List <GenericChangedEntry <Property> >(); ValidateProperties(properties); using (var repository = _repositoryFactory()) { TryAddPredefinedValidationRules(properties); var dbExistProperties = await repository.GetPropertiesByIdsAsync(properties.Where(x => !x.IsTransient()).Select(x => x.Id).ToArray()); foreach (var property in properties) { var modifiedEntity = AbstractTypeFactory <PropertyEntity> .TryCreateInstance().FromModel(property, pkMap); var originalEntity = dbExistProperties.FirstOrDefault(x => x.Id == property.Id); if (originalEntity != null) { changedEntries.Add(new GenericChangedEntry <Property>(property, originalEntity.ToModel(AbstractTypeFactory <Property> .TryCreateInstance()), EntryState.Modified)); modifiedEntity.Patch(originalEntity); //Force set ModifiedDate property to mark a product changed. Special for partial update cases when product table not have changes originalEntity.ModifiedDate = DateTime.UtcNow; } else { repository.Add(modifiedEntity); changedEntries.Add(new GenericChangedEntry <Property>(property, EntryState.Added)); } } //Raise domain events await _eventPublisher.Publish(new PropertyChangingEvent(changedEntries)); //Save changes in database await repository.UnitOfWork.CommitAsync(); pkMap.ResolvePrimaryKeys(); //Reset catalog cache CatalogCacheRegion.ExpireRegion(); await _eventPublisher.Publish(new PropertyChangedEvent(changedEntries)); } }
public virtual async Task SaveChangesAsync(ShoppingCart[] carts) { var pkMap = new PrimaryKeyResolvingMap(); var changedEntries = new List <GenericChangedEntry <ShoppingCart> >(); using (var repository = _repositoryFactory()) { var dataExistCarts = await repository.GetShoppingCartsByIdsAsync(carts.Where(x => !x.IsTransient()).Select(x => x.Id).ToArray()); foreach (var cart in carts) { //Calculate cart totals before save _totalsCalculator.CalculateTotals(cart); var originalEntity = dataExistCarts.FirstOrDefault(x => x.Id == cart.Id); var modifiedEntity = AbstractTypeFactory <ShoppingCartEntity> .TryCreateInstance() .FromModel(cart, pkMap); if (originalEntity != null) { // This extension is allow to get around breaking changes is introduced in EF Core 3.0 that leads to throw // Database operation expected to affect 1 row(s) but actually affected 0 row(s) exception when trying to add the new children entities with manually set keys // https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/breaking-changes#detectchanges-honors-store-generated-key-values repository.TrackModifiedAsAddedForNewChildEntities(originalEntity); changedEntries.Add(new GenericChangedEntry <ShoppingCart>(cart, originalEntity.ToModel(AbstractTypeFactory <ShoppingCart> .TryCreateInstance()), EntryState.Modified)); modifiedEntity.Patch(originalEntity); } else { repository.Add(modifiedEntity); changedEntries.Add(new GenericChangedEntry <ShoppingCart>(cart, EntryState.Added)); } } //Raise domain events await _eventPublisher.Publish(new CartChangeEvent(changedEntries)); await repository.UnitOfWork.CommitAsync(); pkMap.ResolvePrimaryKeys(); ClearCache(carts); await _eventPublisher.Publish(new CartChangedEvent(changedEntries)); } }
public virtual void SaveChanges(CustomerOrder[] orders) { var pkMap = new PrimaryKeyResolvingMap(); var changedEvents = new List <OrderChangedEvent>(); using (var repository = RepositoryFactory()) using (var changeTracker = GetChangeTracker(repository)) { var dataExistOrders = repository.GetCustomerOrdersByIds(orders.Where(x => !x.IsTransient()).Select(x => x.Id).ToArray(), CustomerOrderResponseGroup.Full); foreach (var order in orders) { EnsureThatAllOperationsHaveNumber(order); var originalEntity = dataExistOrders.FirstOrDefault(x => x.Id == order.Id); var originalOrder = originalEntity != null ? (CustomerOrder)originalEntity.ToModel(AbstractTypeFactory <CustomerOrder> .TryCreateInstance()) : order; var changingEvent = new OrderChangeEvent(originalEntity == null ? EntryState.Added : EntryState.Modified, originalOrder, order); OrderChangingPublisher.Publish(changingEvent); changedEvents.Add(new OrderChangedEvent(changingEvent.ChangeState, changingEvent.OrigOrder, changingEvent.ModifiedOrder)); var modifiedEntity = AbstractTypeFactory <CustomerOrderEntity> .TryCreateInstance() .FromModel(order, pkMap) as CustomerOrderEntity; if (originalEntity != null) { changeTracker.Attach(originalEntity); modifiedEntity.Patch(originalEntity); } else { repository.Add(modifiedEntity); } } CommitChanges(repository); pkMap.ResolvePrimaryKeys(); } //Save dynamic properties foreach (var order in orders) { DynamicPropertyService.SaveDynamicPropertyValues(order); } //Raise changed events foreach (var changedEvent in changedEvents) { OrderChangedPublisher.Publish(changedEvent); } }
public virtual async Task SaveChangesAsync(CatalogProduct[] items) { var pkMap = new PrimaryKeyResolvingMap(); var changedEntries = new List <GenericChangedEntry <CatalogProduct> >(); await ValidateProductsAsync(items); using (var repository = _repositoryFactory()) { var dbExistProducts = await repository.GetItemByIdsAsync(items.Where(x => !x.IsTransient()).Select(x => x.Id).ToArray()); foreach (var product in items) { var modifiedEntity = AbstractTypeFactory <ItemEntity> .TryCreateInstance().FromModel(product, pkMap); var originalEntity = dbExistProducts.FirstOrDefault(x => x.Id == product.Id); if (originalEntity != null) { /// This extension is allow to get around breaking changes is introduced in EF Core 3.0 that leads to throw /// Database operation expected to affect 1 row(s) but actually affected 0 row(s) exception when trying to add the new children entities with manually set keys /// https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/breaking-changes#detectchanges-honors-store-generated-key-values repository.TrackModifiedAsAddedForNewChildEntities(originalEntity); changedEntries.Add(new GenericChangedEntry <CatalogProduct>(product, originalEntity.ToModel(AbstractTypeFactory <CatalogProduct> .TryCreateInstance()), EntryState.Modified)); modifiedEntity.Patch(originalEntity); //Force set ModifiedDate property to mark a product changed. Special for partial update cases when product table not have changes originalEntity.ModifiedDate = DateTime.UtcNow; } else { repository.Add(modifiedEntity); changedEntries.Add(new GenericChangedEntry <CatalogProduct>(product, EntryState.Added)); } } await _eventPublisher.Publish(new ProductChangingEvent(changedEntries)); await repository.UnitOfWork.CommitAsync(); pkMap.ResolvePrimaryKeys(); ClearCache(items); await _eventPublisher.Publish(new ProductChangedEvent(changedEntries)); } }
/// <summary> /// Create or update members in database /// </summary> /// <param name="members"></param> public virtual async Task SaveChangesAsync(Member[] members) { var pkMap = new PrimaryKeyResolvingMap(); var changedEntries = new List <GenericChangedEntry <Member> >(); using (var repository = RepositoryFactory()) { var existingMemberEntities = await repository.GetMembersByIdsAsync(members.Where(m => !m.IsTransient()).Select(m => m.Id).ToArray()); foreach (var member in members) { var memberEntityType = AbstractTypeFactory <Member> .AllTypeInfos.Where(t => t.MappedType != null && t.IsAssignableTo(member.MemberType)).Select(t => t.MappedType).FirstOrDefault(); if (memberEntityType != null) { var dataSourceMember = AbstractTypeFactory <MemberEntity> .TryCreateInstance(memberEntityType.Name); if (dataSourceMember != null) { dataSourceMember.FromModel(member, pkMap); var dataTargetMember = existingMemberEntities.FirstOrDefault(m => m.Id == member.Id); if (dataTargetMember != null) { changedEntries.Add(new GenericChangedEntry <Member>(member, dataTargetMember.ToModel(AbstractTypeFactory <Member> .TryCreateInstance(member.MemberType)), EntryState.Modified)); dataSourceMember.Patch(dataTargetMember); } else { repository.Add(dataSourceMember); changedEntries.Add(new GenericChangedEntry <Member>(member, EntryState.Added)); } } } } //Raise domain events await EventPublisher.Publish(new MemberChangingEvent(changedEntries)); await repository.UnitOfWork.CommitAsync(); pkMap.ResolvePrimaryKeys(); await EventPublisher.Publish(new MemberChangedEvent(changedEntries)); } ClearCache(members); }
public async Task SaveChangesAsync(License[] licenses) { var pkMap = new PrimaryKeyResolvingMap(); var changedEntries = new List <GenericChangedEntry <License> >(); using (var repository = _licenseRepositoryFactory()) { var existingEntities = await repository.GetByIdsAsync(licenses.Where(x => !x.IsTransient()).Select(x => x.Id).ToArray()); foreach (var entity in licenses) { //ensure that ActivationCode is filled if (string.IsNullOrEmpty(entity.ActivationCode)) { entity.ActivationCode = Guid.NewGuid().ToString("N").Substring(0, 6).ToUpper(); } var originalEntity = existingEntities.FirstOrDefault(x => x.Id == entity.Id); var originalLicense = originalEntity != null?originalEntity.ToModel(AbstractTypeFactory <License> .TryCreateInstance()) : entity; var sourceEntity = AbstractTypeFactory <LicenseEntity> .TryCreateInstance(); if (sourceEntity != null) { sourceEntity = sourceEntity.FromModel(entity, pkMap); var targetEntity = existingEntities.FirstOrDefault(x => x.Id == entity.Id); if (targetEntity != null) { changedEntries.Add(new GenericChangedEntry <License>(entity, originalLicense, EntryState.Modified)); sourceEntity.Patch(targetEntity); } else { repository.Add(sourceEntity); changedEntries.Add(new GenericChangedEntry <License>(entity, EntryState.Added)); } } } await repository.UnitOfWork.CommitAsync(); await _eventPublisher.Publish(new LicenseChangedEvent(changedEntries)); pkMap.ResolvePrimaryKeys(); } }
public void SaveCustomerReview(CustomerReview item) { if (item == null) { throw new ArgumentNullException(nameof(item)); } var pkMap = new PrimaryKeyResolvingMap(); using (ICustomerReviewRepository repository = _repositoryFactory()) { using (ObservableChangeTracker changeTracker = GetChangeTracker(repository)) { if (!item.IsTransient()) { var sourceEntity = AbstractTypeFactory <CustomerReviewEntity> .TryCreateInstance().FromModel(item, pkMap); var existsEntity = repository.GetCustomerReview(item.Id); if (existsEntity != null) { changeTracker.Attach(existsEntity); sourceEntity.Patch(existsEntity); } else { repository.Add(sourceEntity); } } else { item.Id = Guid.NewGuid().ToString("N"); foreach (var value in item.PropertyValues) { value.ReviewId = item.Id; } var sourceEntity = AbstractTypeFactory <CustomerReviewEntity> .TryCreateInstance().FromModel(item, pkMap); repository.Add(sourceEntity); } CommitChanges(repository); pkMap.ResolvePrimaryKeys(); } } }
public virtual void SaveChanges(ShoppingCart[] carts) { var pkMap = new PrimaryKeyResolvingMap(); var changedEntries = new List <GenericChangedEntry <ShoppingCart> >(); using (var repository = RepositoryFactory()) using (var changeTracker = GetChangeTracker(repository)) { var dataExistCarts = repository.GetShoppingCartsByIds(carts.Where(x => !x.IsTransient()).Select(x => x.Id).ToArray()); foreach (var cart in carts) { //Calculate cart totals before save TotalsCalculator.CalculateTotals(cart); var originalEntity = dataExistCarts.FirstOrDefault(x => x.Id == cart.Id); var modifiedEntity = AbstractTypeFactory <ShoppingCartEntity> .TryCreateInstance() .FromModel(cart, pkMap); if (originalEntity != null) { changeTracker.Attach(originalEntity); var oldEntry = originalEntity.ToModel(AbstractTypeFactory <ShoppingCart> .TryCreateInstance()); DynamicPropertyService.LoadDynamicPropertyValues(oldEntry); changedEntries.Add(new GenericChangedEntry <ShoppingCart>(cart, oldEntry, EntryState.Modified)); modifiedEntity.Patch(originalEntity); } else { repository.Add(modifiedEntity); changedEntries.Add(new GenericChangedEntry <ShoppingCart>(cart, EntryState.Added)); } } //Raise domain events EventPublisher.Publish(new CartChangeEvent(changedEntries)); CommitChanges(repository); pkMap.ResolvePrimaryKeys(); EventPublisher.Publish(new CartChangedEvent(changedEntries)); } //Save dynamic properties foreach (var cart in carts) { DynamicPropertyService.SaveDynamicPropertyValues(cart); } }
public void Update(ShoppingCart[] carts) { var changedCarts = new List <ShoppingCart>(); var pkMap = new PrimaryKeyResolvingMap(); using (var repository = _repositoryFactory()) using (var changeTracker = base.GetChangeTracker(repository)) { foreach (var changedCart in carts) { var origCart = GetById(changedCart.Id); var productIds = changedCart.Items.Select(x => x.ProductId).ToArray(); var products = _productService.GetByIds(productIds, Domain.Catalog.Model.ItemResponseGroup.ItemInfo); foreach (var lineItem in changedCart.Items) { var product = products.FirstOrDefault(x => x.Id == lineItem.ProductId); if (product != null) { lineItem.Product = product; } } _eventPublisher.Publish(new CartChangeEvent(Platform.Core.Common.EntryState.Modified, origCart, changedCart)); var sourceCartEntity = changedCart.ToDataModel(pkMap); var targetCartEntity = repository.GetShoppingCartById(changedCart.Id); if (targetCartEntity == null) { throw new NullReferenceException("targetCartEntity"); } changeTracker.Attach(targetCartEntity); sourceCartEntity.Patch(targetCartEntity); } CommitChanges(repository); pkMap.ResolvePrimaryKeys(); } //Save dynamic properties for carts and all nested objects foreach (var cart in carts) { _dynamicPropertyService.SaveDynamicPropertyValues(cart); } }
public virtual void SavePricelistAssignments(coreModel.PricelistAssignment[] assignments) { var pkMap = new PrimaryKeyResolvingMap(); using (var repository = _repositoryFactory()) using (var changeTracker = GetChangeTracker(repository)) { var assignmentsIds = assignments.Select(x => x.Id).Where(x => x != null).Distinct().ToArray(); var alreadyExistEntities = repository.GetPricelistAssignmentsById(assignmentsIds); foreach (var assignment in assignments) { //Serialize condition expression if (assignment.DynamicExpression != null && assignment.DynamicExpression.Children != null) { var conditionExpression = assignment.DynamicExpression.GetConditionExpression(); assignment.ConditionExpression = _expressionSerializer.SerializeExpression(conditionExpression); //Clear availableElements in expression (for decrease size) assignment.DynamicExpression.AvailableChildren = null; var allBlocks = ((DynamicExpression)assignment.DynamicExpression).Traverse(x => x.Children); foreach (var block in allBlocks) { block.AvailableChildren = null; } assignment.PredicateVisualTreeSerialized = JsonConvert.SerializeObject(assignment.DynamicExpression); } var sourceEntity = AbstractTypeFactory <dataModel.PricelistAssignmentEntity> .TryCreateInstance().FromModel(assignment, pkMap); var targetEntity = alreadyExistEntities.FirstOrDefault(x => x.Id == assignment.Id); if (targetEntity != null) { changeTracker.Attach(targetEntity); sourceEntity.Patch(targetEntity); } else { repository.Add(sourceEntity); } } CommitChanges(repository); pkMap.ResolvePrimaryKeys(); ResetCache(); } }
protected virtual void SaveChanges(CatalogProduct[] products, bool disableValidation = false) { var pkMap = new PrimaryKeyResolvingMap(); var changedEntries = new List <GenericChangedEntry <CatalogProduct> >(); ValidateProducts(products); using (var repository = _repositoryFactory()) using (var changeTracker = GetChangeTracker(repository)) { var dbExistProducts = repository.GetItemByIds(products.Where(x => !x.IsTransient()).Select(x => x.Id).ToArray(), ItemResponseGroup.ItemLarge); foreach (var product in products) { var modifiedEntity = AbstractTypeFactory <ItemEntity> .TryCreateInstance().FromModel(product, pkMap); var originalEntity = dbExistProducts.FirstOrDefault(x => x.Id == product.Id); if (originalEntity != null) { changeTracker.Attach(originalEntity); changedEntries.Add(new GenericChangedEntry <CatalogProduct>(product, originalEntity.ToModel(AbstractTypeFactory <CatalogProduct> .TryCreateInstance()), EntryState.Modified)); modifiedEntity.Patch(originalEntity); //Force set ModifiedDate property to mark a product changed. Special for partial update cases when product table not have changes originalEntity.ModifiedDate = DateTime.UtcNow; } else { repository.Add(modifiedEntity); changedEntries.Add(new GenericChangedEntry <CatalogProduct>(product, EntryState.Added)); } } _eventPublisher.Publish(new ProductChangingEvent(changedEntries)); CommitChanges(repository); pkMap.ResolvePrimaryKeys(); _eventPublisher.Publish(new ProductChangedEvent(changedEntries)); } //Update SEO var productsWithVariations = products.Concat(products.Where(x => x.Variations != null).SelectMany(x => x.Variations)).OfType <ISeoSupport>().ToArray(); _commerceService.UpsertSeoForObjects(productsWithVariations); }
public coreModel.Organization Create(coreModel.Organization organization) { var pkMap = new PrimaryKeyResolvingMap(); var entity = organization.ToDataModel(pkMap); using (var repository = _repositoryFactory()) { repository.Add(entity); CommitChanges(repository); pkMap.ResolvePrimaryKeys(); } _dynamicPropertyService.SaveDynamicPropertyValues(organization); var retVal = GetById(entity.Id); return(retVal); }
public void UpsertSeoInfos(coreModel.SeoInfo[] seoinfos) { var pkMap = new PrimaryKeyResolvingMap(); using (var repository = _repositoryFactory()) using (var changeTracker = GetChangeTracker(repository)) { var alreadyExistSeoInfos = repository.GetSeoByIds(seoinfos.Select(x => x.Id).ToArray()); var target = new { SeoInfos = new ObservableCollection <dataModel.SeoUrlKeyword>(alreadyExistSeoInfos) }; var source = new { SeoInfos = new ObservableCollection <dataModel.SeoUrlKeyword>(seoinfos.Select(x => AbstractTypeFactory <dataModel.SeoUrlKeyword> .TryCreateInstance().FromModel(x, pkMap))) }; changeTracker.Attach(target); source.SeoInfos.Patch(target.SeoInfos, (sourceSeoUrlKeyword, targetSeoUrlKeyword) => sourceSeoUrlKeyword.Patch(targetSeoUrlKeyword)); repository.UnitOfWork.Commit(); pkMap.ResolvePrimaryKeys(); } }
public coreModel.DynamicContentItem CreateContent(coreModel.DynamicContentItem content) { var pkMap = new PrimaryKeyResolvingMap(); var entity = content.ToDataModel(pkMap); using (var repository = _repositoryFactory()) { repository.Add(entity); CommitChanges(repository); pkMap.ResolvePrimaryKeys(); } _dynamicPropertyService.SaveDynamicPropertyValues(content); var retVal = GetContentItemById(entity.Id); return(retVal); }
public void SaveCustomerReviewVotes(CustomerReviewVote[] items) { if (items == null) { throw new ArgumentNullException(nameof(items)); } var pkMap = new PrimaryKeyResolvingMap(); int i = 0; #pragma warning disable S3353 // Unchanged local variables should be "const" #pragma warning disable S1481 // Unused local variables should be removed int r = 0; #pragma warning restore S1481 // Unused local variables should be removed #pragma warning restore S3353 // Unchanged local variables should be "const" using (var repository = _repositoryFactory()) { using (var changeTracker = GetChangeTracker(repository)) { var alreadyExistEntities = repository.GetVoteByIds(items.Where(m => !m.IsTransient()).Select(x => x.Id).ToArray()); foreach (var derivativeContract in items) { var sourceEntity = AbstractTypeFactory <CustomerReviewVoteEntity> .TryCreateInstance().FromModel(derivativeContract, pkMap); var targetEntity = alreadyExistEntities.FirstOrDefault(x => x.Id == sourceEntity.Id); if (targetEntity != null) { changeTracker.Attach(targetEntity); sourceEntity.Patch(targetEntity); } else { repository.Add(sourceEntity); } } var reviewIds = items.Select(x => x.CustomerReviewId).ToArray(); UpdateCustomerReviewVotesCount(repository, reviewIds); CommitChanges(repository); pkMap.ResolvePrimaryKeys(); } } }
public void SaveCustomerReviews(CustomerReview[] items) { if (items == null) { throw new ArgumentNullException(nameof(items)); } List <string> productIds = new List <string>(); var pkMap = new PrimaryKeyResolvingMap(); using (var repository = _repositoryFactory()) { using (var changeTracker = GetChangeTracker(repository)) { var alreadyExistEntities = repository.GetByIds(items.Where(m => !m.IsTransient()).Select(x => x.Id).ToArray()); foreach (var derivativeContract in items) { var sourceEntity = AbstractTypeFactory <CustomerReviewEntity> .TryCreateInstance().FromModel(derivativeContract, pkMap); var targetEntity = alreadyExistEntities.FirstOrDefault(x => x.Id == sourceEntity.Id); if (targetEntity != null) { changeTracker.Attach(targetEntity); sourceEntity.Patch(targetEntity); } else { repository.Add(sourceEntity); } productIds.Add(derivativeContract.ProductId); } CommitChanges(repository); pkMap.ResolvePrimaryKeys(); } IEnumerable <string> distinctProductIds = productIds.Distinct(); foreach (string productId in distinctProductIds) { repository.RecalcRatingForProduct(productId); } CommitChanges(repository); } }
public virtual async Task SavePlansAsync(PaymentPlan[] plans) { var pkMap = new PrimaryKeyResolvingMap(); var changedEntries = new List <GenericChangedEntry <PaymentPlan> >(); using (var repository = _subscriptionRepositoryFactory()) { var existPlanEntities = await repository.GetPaymentPlansByIdsAsync(plans.Where(x => !x.IsTransient()).Select(x => x.Id).ToArray()); foreach (var paymentPlan in plans) { var sourcePlanEntity = AbstractTypeFactory <PaymentPlanEntity> .TryCreateInstance(); if (sourcePlanEntity != null) { sourcePlanEntity = sourcePlanEntity.FromModel(paymentPlan, pkMap) as PaymentPlanEntity; var targetPlanEntity = existPlanEntities.FirstOrDefault(x => x.Id == paymentPlan.Id); if (targetPlanEntity != null) { changedEntries.Add(new GenericChangedEntry <PaymentPlan>(paymentPlan, targetPlanEntity.ToModel(AbstractTypeFactory <PaymentPlan> .TryCreateInstance()), EntryState.Modified)); sourcePlanEntity.Patch(targetPlanEntity); } else { repository.Add(sourcePlanEntity); changedEntries.Add(new GenericChangedEntry <PaymentPlan>(paymentPlan, EntryState.Added)); } } } //Raise domain events await _eventPublisher.Publish(new PaymentPlanChangingEvent(changedEntries)); await repository.UnitOfWork.CommitAsync(); pkMap.ResolvePrimaryKeys(); ClearCacheFor(plans); await _eventPublisher.Publish(new PaymentPlanChangedEvent(changedEntries)); } }
protected virtual void SaveChanges(Category[] categories) { var pkMap = new PrimaryKeyResolvingMap(); var changedEntries = new List <GenericChangedEntry <Category> >(); ValidateCategoryProperties(categories); using (var repository = _repositoryFactory()) using (var changeTracker = GetChangeTracker(repository)) { var dbExistCategories = repository.GetCategoriesByIds(categories.Where(x => !x.IsTransient()).Select(x => x.Id).ToArray(), CategoryResponseGroup.Full); foreach (var category in categories) { var originalEntity = dbExistCategories.FirstOrDefault(x => x.Id == category.Id); var modifiedEntity = AbstractTypeFactory <CategoryEntity> .TryCreateInstance().FromModel(category, pkMap); if (originalEntity != null) { changeTracker.Attach(originalEntity); changedEntries.Add(new GenericChangedEntry <Category>(category, originalEntity.ToModel(AbstractTypeFactory <Category> .TryCreateInstance()), EntryState.Modified)); modifiedEntity.Patch(originalEntity); //Force set ModifiedDate property to mark a product changed. Special for partial update cases when product table not have changes originalEntity.ModifiedDate = DateTime.UtcNow; } else { repository.Add(modifiedEntity); changedEntries.Add(new GenericChangedEntry <Category>(category, EntryState.Added)); } } _eventPublisher.Publish(new CategoryChangingEvent(changedEntries)); CommitChanges(repository); pkMap.ResolvePrimaryKeys(); //Reset cached categories and catalogs ResetCache(); _eventPublisher.Publish(new CategoryChangedEvent(changedEntries)); } //Need add seo separately _commerceService.UpsertSeoForObjects(categories.OfType <ISeoSupport>().ToArray()); }
public virtual async Task SaveChangesAsync(CatalogProduct[] products) { var pkMap = new PrimaryKeyResolvingMap(); var changedEntries = new List <GenericChangedEntry <CatalogProduct> >(); await ValidateProductsAsync(products); using (var repository = _repositoryFactory()) { var dbExistProducts = await repository.GetItemByIdsAsync(products.Where(x => !x.IsTransient()).Select(x => x.Id).ToArray()); foreach (var product in products) { var modifiedEntity = AbstractTypeFactory <ItemEntity> .TryCreateInstance().FromModel(product, pkMap); var originalEntity = dbExistProducts.FirstOrDefault(x => x.Id == product.Id); if (originalEntity != null) { changedEntries.Add(new GenericChangedEntry <CatalogProduct>(product, originalEntity.ToModel(AbstractTypeFactory <CatalogProduct> .TryCreateInstance()), EntryState.Modified)); modifiedEntity.Patch(originalEntity); //Force set ModifiedDate property to mark a product changed. Special for partial update cases when product table not have changes originalEntity.ModifiedDate = DateTime.UtcNow; } else { repository.Add(modifiedEntity); changedEntries.Add(new GenericChangedEntry <CatalogProduct>(product, EntryState.Added)); } } await _eventPublisher.Publish(new ProductChangingEvent(changedEntries)); await repository.UnitOfWork.CommitAsync(); pkMap.ResolvePrimaryKeys(); await _eventPublisher.Publish(new ProductChangedEvent(changedEntries)); } ClearCache(products); }
public ShoppingCart Create(ShoppingCart cart) { var pkMap = new PrimaryKeyResolvingMap(); //Do business logic on temporary order object _eventPublisher.Publish(new CartChangeEvent(Platform.Core.Common.EntryState.Added, null, cart)); var entity = cart.ToDataModel(pkMap); ShoppingCart retVal = null; using (var repository = _repositoryFactory()) { repository.Add(entity); CommitChanges(repository); pkMap.ResolvePrimaryKeys(); } retVal = GetById(entity.Id); return(retVal); }
public coreModel.Category Create(coreModel.Category category) { if (category == null) { throw new ArgumentNullException("category"); } var pkMap = new PrimaryKeyResolvingMap(); var dbCategory = category.ToDataModel(pkMap); using (var repository = _catalogRepositoryFactory()) { repository.Add(dbCategory); CommitChanges(repository); pkMap.ResolvePrimaryKeys(); } //Need add seo separately _commerceService.UpsertSeoForObjects(new[] { category }); return(GetById(dbCategory.Id, Domain.Catalog.Model.CategoryResponseGroup.Info)); }
public virtual void SaveChanges(IEnumerable <Category> categories) { var pkMap = new PrimaryKeyResolvingMap(); var changedEntries = new List <GenericChangedEntry <Category> >(); ValidateCategoryProperties(categories); using (var repository = _repositoryFactory()) { var dbExistCategories = repository.GetCategoriesByIds(categories.Where(x => !x.IsTransient()).Select(x => x.Id).ToArray()); foreach (var category in categories) { var originalEntity = dbExistCategories.FirstOrDefault(x => x.Id == category.Id); var modifiedEntity = AbstractTypeFactory <CategoryEntity> .TryCreateInstance().FromModel(category, pkMap); if (originalEntity != null) { changedEntries.Add(new GenericChangedEntry <Category>(category, originalEntity.ToModel(AbstractTypeFactory <Category> .TryCreateInstance()), EntryState.Modified)); modifiedEntity.Patch(originalEntity); //Force set ModifiedDate property to mark a product changed. Special for partial update cases when product table not have changes originalEntity.ModifiedDate = DateTime.UtcNow; } else { repository.Add(modifiedEntity); changedEntries.Add(new GenericChangedEntry <Category>(category, EntryState.Added)); } } //Raise domain events _eventPublisher.Publish(new CategoryChangingEvent(changedEntries)); //Save changes in database repository.UnitOfWork.Commit(); pkMap.ResolvePrimaryKeys(); _eventPublisher.Publish(new CategoryChangedEvent(changedEntries)); //Reset catalog cache CatalogCacheRegion.ExpireRegion(); } //Need add seo separately _seoService.SaveSeoForObjectsAsync(categories.OfType <ISeoSupport>().ToArray()); }