/// <summary>
        /// Inserts (creates) a simple standard report for a given advertiser.
        /// </summary>
        /// <param name="userProfileId">The ID number of the DFA user profile to run this request as.</param>
        /// <param name="advertiser">The advertiser who the report is about.</param>
        /// <param name="startDate">The starting date of the report.</param>
        /// <param name="endDate">The ending date of the report.</param>
        /// <returns>The newly created report</returns>
        public Report Insert(long userProfileId, DimensionValue advertiser, DateTime startDate, DateTime endDate)
        {
            Console.WriteLine("=================================================================");
            Console.WriteLine("Creating a new standard report for advertiser {0}%n", advertiser.Value);
            Console.WriteLine("=================================================================");

            // Create a report.
            var report = new Report();
            report.Name = string.Format("API Report: Advertiser {0}", advertiser.Value);
            report.FileName = "api_report_files";
            // Set the type of report you want to create. Available report types can be found in the description of 
            // the type property: https://developers.google.com/doubleclick-advertisers/reporting/v1.1/reports
            report.Type = "FLOODLIGHT";
            report.Type = "STANDARD";

            // Create criteria.
            var criteria = new Report.CriteriaData();
            criteria.DateRange = new DateRange
            {
                StartDate = DfaReportingDateConverterUtil.convert(startDate),
                EndDate = DfaReportingDateConverterUtil.convert(endDate)
            };
            // Set the dimensions, metrics, and filters you want in the report. The available values can be found 
            // here: https://developers.google.com/doubleclick-advertisers/reporting/v1.1/dimensions
            criteria.Dimensions = new List<SortedDimension> { new SortedDimension { Name = "dfa:advertiser" } };
            criteria.MetricNames = new List<string> { "dfa:clicks", "dfa:impressions" };
            criteria.DimensionFilters = new List<DimensionValue> { advertiser };

            report.Criteria = criteria;
            Report result = service.Reports.Insert(report, userProfileId).Execute();
            Console.WriteLine("Created report with ID \"{0}\" and display name \"{1}\"", result.Id, result.Name);
            Console.WriteLine();
            return result;
        }
예제 #2
0
        private DimensionValue LastDimensions(DateTime?statsLastSuccess, DateTime?statsLastFailure, TimeSpan fiveMinutes,
                                              string dimensionName)
        {
            DateTime?lastSuccessIn5Min = statsLastSuccess.HasValue && (DateTime.Now - statsLastSuccess) < fiveMinutes
                ? statsLastSuccess
                : null;

            DateTime?lastFailureIn5Min = statsLastFailure.HasValue && (DateTime.Now - statsLastFailure) < fiveMinutes
                ? statsLastFailure
                : null;
            double last5Value;

            if (lastSuccessIn5Min.HasValue && lastFailureIn5Min.HasValue)
            {
                last5Value = 0.0;
            }
            else
            {
                last5Value = 1000;
            }

            double fiveMinuteDeltaSinceLastSuccessOrFailure = Hash(last5Value);

            DimensionValue last5Dim =
                new DimensionValue(
                    _dimensionKeyFactory.GetOrCreate(dimensionName),
                    fiveMinuteDeltaSinceLastSuccessOrFailure);

            return(last5Dim);
        }
        private static void CreateAndRunStandardReport(DfareportingService service, long userProfileId)
        {
            DimensionValueList advertisers = new GetDimensionValuesHelper(service).Query(
                "dfa:advertiser", userProfileId, StartDate, EndDate, MaxListPageSize);

            if (advertisers.Items.Count > 0)
            {
                // Get an advertiser to report on.
                DimensionValue advertiser = advertisers.Items[0];

                Report standardReport = new CreateStandardReportHelper(service).Insert(
                    userProfileId, advertiser, StartDate, EndDate);

                // List all of the fields compatible with this standard report.
                new GetCompatibleFieldsHelper(service).Run(userProfileId, standardReport);

                File file = new GenerateReportFileHelper(service).Run(userProfileId, standardReport, true);

                if (file != null)
                {
                    // If the report file generation did not fail, display results.
                    new DownloadReportFileHelper(service).Run(file);
                }
            }
        }
        /// <summary>
        /// Inserts (creates) a simple Floodlight report for a given Floodlight Configuration ID.
        /// </summary>
        /// <param name="userProfileId">
        /// The ID number of the DFA user profile to run this request as.
        /// </param>
        /// <param name="floodlightConfigId">
        /// The Floodlight configuration ID the report is about.
        /// </param>
        /// <param name="startDate">The starting date of the report.</param>
        /// <param name="endDate">The ending date of the report.</param>
        /// <returns>The newly created report</returns>
        public Report Insert(long userProfileId, DimensionValue floodlightConfigId,
                             DateTime startDate, DateTime endDate)
        {
            Console.WriteLine("=================================================================");
            Console.WriteLine("Creating a new floodlight report for Floodlight config ID {0}",
                              floodlightConfigId.Value);
            Console.WriteLine("=================================================================");

            // Create a report.
            Report report = new Report();

            report.Name = string.Format("API Floodlight Report: Floodlight ID {0}",
                                        floodlightConfigId.Value);
            report.FileName = "api_floodlight_report_files";
            // Set the type of report you want to create. Available report types can be found in
            // the description of the type property:
            // https://developers.google.com/doubleclick-advertisers/reporting/v1.3/reports
            report.Type = "FLOODLIGHT";

            // Create criteria.
            var criteria = new Report.FloodlightCriteriaData();

            criteria.DateRange = new DateRange
            {
                StartDate = DfaReportingDateConverterUtil.convert(startDate),
                EndDate   = DfaReportingDateConverterUtil.convert(endDate)
            };
            // Set the dimensions, metrics, and filters you want in the report. The available
            // values can be found here:
            // https://developers.google.com/doubleclick-advertisers/reporting/v1.3/dimensions
            criteria.Dimensions = new List <SortedDimension> {
                new SortedDimension {
                    Name = "dfa:floodlightConfigId"
                },
                new SortedDimension {
                    Name = "dfa:activity"
                },
                new SortedDimension {
                    Name = "dfa:advertiser"
                }
            };
            criteria.MetricNames = new List <string> {
                "dfa:activityClickThroughConversions",
                "dfa:activityClickThroughRevenue",
                "dfa:activityViewThroughConversions",
                "dfa:activityViewThroughRevenue"
            };
            criteria.DimensionFilters = new List <DimensionValue> {
                floodlightConfigId
            };

            report.FloodlightCriteria = criteria;
            Report result = service.Reports.Insert(report, userProfileId).Execute();

            Console.WriteLine("Created report with ID \"{0}\" and display name \"{1}\"", result.Id,
                              result.Name);
            Console.WriteLine();
            return(result);
        }
        /// <summary>
        /// Inserts (creates) a simple standard report for a given advertiser.
        /// </summary>
        /// <param name="userProfileId">
        /// The ID number of the DFA user profile to run this request as.
        /// </param>
        /// <param name="advertiser">The advertiser who the report is about.</param>
        /// <param name="startDate">The starting date of the report.</param>
        /// <param name="endDate">The ending date of the report.</param>
        /// <returns>The newly created report</returns>
        public Report Insert(long userProfileId, DimensionValue advertiser, DateTime startDate,
                             DateTime endDate)
        {
            Console.WriteLine("=================================================================");
            Console.WriteLine("Creating a new standard report for advertiser {0}%n",
                              advertiser.Value);
            Console.WriteLine("=================================================================");

            // Create a report.
            var report = new Report();

            report.Name     = string.Format("API Report: Advertiser {0}", advertiser.Value);
            report.FileName = "api_report_files";
            // Set the type of report you want to create. Available report types can be found in
            //the description of the type property:
            // https://developers.google.com/doubleclick-advertisers/reporting/v1.3/reports
            report.Type = "FLOODLIGHT";
            report.Type = "STANDARD";

            // Create criteria.
            var criteria = new Report.CriteriaData();

            criteria.DateRange = new DateRange
            {
                StartDate = DfaReportingDateConverterUtil.convert(startDate),
                EndDate   = DfaReportingDateConverterUtil.convert(endDate)
            };
            // Set the dimensions, metrics, and filters you want in the report. The available
            // values can be found here:
            // https://developers.google.com/doubleclick-advertisers/reporting/v1.3/dimensions
            criteria.Dimensions = new List <SortedDimension> {
                new SortedDimension {
                    Name = "dfa:advertiser"
                }
            };
            criteria.MetricNames = new List <string> {
                "dfa:clicks", "dfa:impressions"
            };
            criteria.DimensionFilters = new List <DimensionValue> {
                advertiser
            };

            report.Criteria = criteria;
            Report result = service.Reports.Insert(report, userProfileId).Execute();

            Console.WriteLine("Created report with ID \"{0}\" and display name \"{1}\"",
                              result.Id, result.Name);
            Console.WriteLine();
            return(result);
        }
        private async Task <DimensionValue> GetDimensionValueWithRelatedEntities(
            string dimensionValueValue,
            MasterDataContext ctx)
        {
            Check.IsNotNull(dimensionValueValue);
            Check.IsNotNull(ctx);

            DimensionValue res = await ctx.DimensionValues
                                 .Include(i => i.DimensionDimensionValues)
                                 .FirstOrDefaultAsync(p => p.Value == dimensionValueValue)
                                 .ConfigureAwait(false);

            return(res);
        }
        /// <summary>
        /// Inserts (creates) a simple Floodlight report for a given Floodlight Configuration ID.
        /// </summary>
        /// <param name="userProfileId">
        /// The ID number of the DFA user profile to run this request as.
        /// </param>
        /// <param name="floodlightConfigId">
        /// The Floodlight configuration ID the report is about.
        /// </param>
        /// <param name="startDate">The starting date of the report.</param>
        /// <param name="endDate">The ending date of the report.</param>
        /// <returns>The newly created report</returns>
        public Report Insert(long userProfileId, DimensionValue floodlightConfigId,
            DateTime startDate, DateTime endDate)
        {
            Console.WriteLine("=================================================================");
            Console.WriteLine("Creating a new floodlight report for Floodlight config ID {0}",
                floodlightConfigId.Value);
            Console.WriteLine("=================================================================");

            // Create a report.
            Report report = new Report();
            report.Name = string.Format("API Floodlight Report: Floodlight ID {0}",
                floodlightConfigId.Value);
            report.FileName = "api_floodlight_report_files";
            // Set the type of report you want to create. Available report types can be found in
            // the description of the type property:
            // https://developers.google.com/doubleclick-advertisers/reporting/v1.3/reports
            report.Type = "FLOODLIGHT";

            // Create criteria.
            var criteria = new Report.FloodlightCriteriaData();
            criteria.DateRange = new DateRange
            {
                StartDate = DfaReportingDateConverterUtil.convert(startDate),
                EndDate = DfaReportingDateConverterUtil.convert(endDate)
            };
            // Set the dimensions, metrics, and filters you want in the report. The available
            // values can be found here:
            // https://developers.google.com/doubleclick-advertisers/reporting/v1.3/dimensions
            criteria.Dimensions = new List<SortedDimension> {
                new SortedDimension { Name = "dfa:floodlightConfigId" },
                new SortedDimension { Name = "dfa:activity" },
                new SortedDimension { Name = "dfa:advertiser" } };
            criteria.MetricNames = new List<string> {
                "dfa:activityClickThroughConversions",
                "dfa:activityClickThroughRevenue",
                "dfa:activityViewThroughConversions",
                "dfa:activityViewThroughRevenue" };
            criteria.DimensionFilters = new List<DimensionValue> { floodlightConfigId };

            report.FloodlightCriteria = criteria;
            Report result = service.Reports.Insert(report, userProfileId).Execute();
            Console.WriteLine("Created report with ID \"{0}\" and display name \"{1}\"", result.Id,
                result.Name);
            Console.WriteLine();
            return result;
        }
예제 #8
0
        public static string BuildNavigationLink(NavigationResult navigation, DimensionValue refinement)
        {
            string link = null;
            List<String> navStates = new List<string>();

            foreach (var item in navigation.AppliedFiltersResult.DimensionValues)
            {
                if (!(item.Dimension.Id == refinement.Dimension.Id
                    && refinement.Dimension.MultiSelect == MultiSelect.None
                    && refinement.Parent != null))
                {
                    link = link + "/" + item.Dimension.DisplayName + "/" + item.DisplayName;
                    navStates.Add(Base36Encode(long.Parse(item.Id)));
                }

            }
            navStates.Add(Base36Encode(long.Parse(refinement.Id)));
            link = link + "/" + refinement.Dimension.DisplayName + "/" + refinement.DisplayName + "/" + String.Join("Z", navStates);
            return link.Replace(' ', '-');
        }
        private static void CreateAndRunFloodlightReport(DfareportingService service, long userProfileId)
        {
            DimensionValueList floodlightConfigIds = new GetDimensionValuesHelper(service).Query(
                "dfa:floodlightConfigId", userProfileId, StartDate, EndDate, MaxListPageSize);

            if (floodlightConfigIds.Items.Count > 0)
            {
                // Get a Floodlight Config ID, so we can run the rest of the samples.
                DimensionValue floodlightConfigId = floodlightConfigIds.Items[0];

                Report floodlightReport = new CreateFloodlightReportHelper(service).Insert(
                    userProfileId, floodlightConfigId, StartDate, EndDate);
                File file = new GenerateReportFileHelper(service).Run(userProfileId, floodlightReport, false);

                if (file != null)
                {
                    // If the report file generation did not fail, display results.
                    new DownloadReportFileHelper(service).Run(file);
                }
            }
        }
        public override void WriteTo(XElement xE)
        {
            base.WriteTo(xE);
            XmlUtility.SetXsiType(xE, "https://adwords.google.com/api/adwords/cm/v201609", "ProductBiddingCategoryData");
            XElement xItem = null;

            if (DimensionValue != null)
            {
                xItem = new XElement(XName.Get("dimensionValue", "https://adwords.google.com/api/adwords/cm/v201609"));
                DimensionValue.WriteTo(xItem);
                xE.Add(xItem);
            }
            if (ParentDimensionValue != null)
            {
                xItem = new XElement(XName.Get("parentDimensionValue", "https://adwords.google.com/api/adwords/cm/v201609"));
                ParentDimensionValue.WriteTo(xItem);
                xE.Add(xItem);
            }
            if (Country != null)
            {
                xItem = new XElement(XName.Get("country", "https://adwords.google.com/api/adwords/cm/v201609"));
                xItem.Add(Country);
                xE.Add(xItem);
            }
            if (Status != null)
            {
                xItem = new XElement(XName.Get("status", "https://adwords.google.com/api/adwords/cm/v201609"));
                xItem.Add(Status.Value.ToXmlValue());
                xE.Add(xItem);
            }
            if (DisplayValue != null)
            {
                foreach (var displayValueItem in DisplayValue)
                {
                    xItem = new XElement(XName.Get("displayValue", "https://adwords.google.com/api/adwords/cm/v201609"));
                    displayValueItem.WriteTo(xItem);
                    xE.Add(xItem);
                }
            }
        }
예제 #11
0
        public static string BuildBreadCrumbLink(NavigationResult navigation, DimensionValue refinement)
        {
            string link = null;
            List<String> navStates = new List<string>();

            foreach (var item in navigation.AppliedFiltersResult.DimensionValues)
            {

                if (item.Id == refinement.Id)
                {
                    link = link + "/" + item.Dimension.DisplayName + "/" + item.DisplayName;
                    navStates.Add(Base36Encode(long.Parse(item.Id)));
                    break;
                }
                else
                {
                    link = link + "/" + item.Dimension.DisplayName + "/" + item.DisplayName;
                    navStates.Add(Base36Encode(long.Parse(item.Id)));
                }
            }

            link = link + "/" + String.Join("Z", navStates);
            return link.Replace(' ', '-');
        }
예제 #12
0
        private Expression <Func <ElementContent, bool> > buildExpression()
        {
            // Build up an Expression of a Function that accepts an Atom and returns bool that
            // will be used as a "where" clause.

            // Define an parameter "a" that will be passed into function.
            var elementParam = Expression.Parameter(typeof(ElementContent), "e");

            Expression whereExp;

            // Start with a.NameSpace = NameSpace
            whereExp = propertyEqualEqualConst(elementParam, "NameSpace", NameSpace);

            // Add "&& a.Name = Name" to function if this.Name is specified.
            if (!string.IsNullOrWhiteSpace(Name))
            {
                var nameEqualExp = propertyEqualEqualConst(elementParam, "Name", Name);
                whereExp = BinaryExpression.And(whereExp, nameEqualExp);
            }

            // Add in criteria of Pages
            if (Pages != null)
            {
                foreach (var page in Pages)
                {
                    if (!string.IsNullOrWhiteSpace(page))
                    {
                        PropertyInfo       propertyInfo = typeof(ElementContent).GetProperty("Pages");
                        MemberExpression   m            = Expression.MakeMemberAccess(elementParam, propertyInfo);
                        ConstantExpression c            = Expression.Constant(page, typeof(string));
                        MethodInfo         mi           = typeof(List <string>).GetMethod("Contains", new Type[] { typeof(string) });
                        var e1 = Expression.Call(m, mi, c);

                        whereExp = BinaryExpression.And(whereExp, e1);
                    }
                }
            }

            // Add in criteria for dimensions
            if (Dimensions != null)
            {
                foreach (var dimensionCriteria in Dimensions)
                {
                    // TODO: Add And Expression for metadataCriterion to whereExp
                    if (!string.IsNullOrWhiteSpace(dimensionCriteria.DimensionName) &&
                        !string.IsNullOrWhiteSpace(dimensionCriteria.DimensionValue))
                    {
                        PropertyInfo     propertyInfo = typeof(ElementContent).GetProperty("Dimensions");
                        MemberExpression m            = Expression.MakeMemberAccess(elementParam, propertyInfo);
                        var d = new DimensionValue()
                        {
                            DimensionName  = dimensionCriteria.DimensionName,
                            DimensionValue = dimensionCriteria.DimensionValue
                        };
                        ConstantExpression c  = Expression.Constant(d, typeof(DimensionValue));
                        MethodInfo         mi = typeof(List <DimensionValue>).GetMethod("Contains", new Type[] { typeof(DimensionValue) });
                        var e1 = Expression.Call(m, mi, c);

                        whereExp = BinaryExpression.And(whereExp, e1);
                    }
                }
            }

            // TODO: Add criteria for metadata

            // Convert the Expression to a Lambda Expression
            return(Expression.Lambda <Func <ElementContent, bool> >(whereExp, new ParameterExpression[] { elementParam }));
        }
        public async Task <DimensionValue> AddDimensionValueAsync(
            DimensionValue dimensionValue,
            long dimensionId)
        {
            try
            {
                Check.IsNotNull(dimensionValue);
                Check.AreNotEqual(dimensionId, 0);

                await _masterDataValidators.DimensionValueValidator.ValidateAsync(dimensionValue, o =>
                {
                    o.IncludeRuleSets(ValidatorRulesets.AddNewDimensionValue);
                    o.ThrowOnFailures();
                }).ConfigureAwait(false);

                using (MasterDataContext ctx = new MasterDataContext(_dbContextOptions))
                {
                    using (IDbContextTransaction transaction = await ctx.Database.BeginTransactionAsync()
                                                               .ConfigureAwait(false))
                    {
                        try
                        {
                            // Check whether dimension exist
                            DomainModel.Dimension dimension = await ctx.Dimensions
                                                              .FindAsync(dimensionId)
                                                              .ConfigureAwait(true);

                            string msg = $"Dimension with Id {dimensionId} doesnt exists";
                            Check.IsNotNull(dimension, msg);

                            // check whether value already exist
                            DimensionValue doesDimensionValueExists = await ctx.DimensionValues
                                                                      .FirstOrDefaultAsync(w => w.Value == dimensionValue.Value)
                                                                      .ConfigureAwait(false);

                            if (doesDimensionValueExists != null)
                            {
                                // check whether dimension - dimension value pair exist
                                DimensionDimensionValue doesDimensionDimensionValueRelationExist = await ctx
                                                                                                   .DimensionDimensionValues
                                                                                                   .FirstOrDefaultAsync(p => p.DimensionId == dimension.Id &&
                                                                                                                        p.DimensionValueId == doesDimensionValueExists.Id)
                                                                                                   .ConfigureAwait(false);

                                // if doesnt exists create one
                                if (doesDimensionDimensionValueRelationExist == null)
                                {
                                    DimensionDimensionValue dimensionDimensionValue = new DimensionDimensionValue
                                    {
                                        DimensionId      = dimension.Id,
                                        DimensionValueId = doesDimensionValueExists.Id,
                                    };
                                    await ctx.DimensionDimensionValues.AddAsync(dimensionDimensionValue)
                                    .ConfigureAwait(false);

                                    await ctx.SaveChangesAsync().ConfigureAwait(false);

                                    await transaction.CommitAsync().ConfigureAwait(false);

                                    return(doesDimensionValueExists);
                                }

                                // include all related entities
                                // return doesDimensionValueExists;
                                DimensionValue alreadyExistingDimensionValue =
                                    await GetDimensionValueWithRelatedEntities(
                                        dimensionValue.Value, ctx)
                                    .ConfigureAwait(false);

                                return(alreadyExistingDimensionValue);
                            }

                            // create dimension value entry
                            DimensionValue newDimensionValue = new DimensionValue
                            {
                                Value = dimensionValue.Value,
                            };
                            await ctx.DimensionValues.AddAsync(newDimensionValue)
                            .ConfigureAwait(false);

                            await ctx.SaveChangesAsync().ConfigureAwait(false);

                            // create dimension - dimension value relation
                            DimensionDimensionValue newlyAddedDimensionValue = new DimensionDimensionValue
                            {
                                DimensionId      = dimension.Id,
                                DimensionValueId = newDimensionValue.Id,
                            };
                            await ctx.DimensionDimensionValues.AddAsync(newlyAddedDimensionValue)
                            .ConfigureAwait(false);

                            await ctx.SaveChangesAsync().ConfigureAwait(false);

                            await transaction.CommitAsync().ConfigureAwait(false);

                            DimensionValue createdDimensionValue =
                                await GetDimensionValueWithRelatedEntities(dimensionValue.Value, ctx)
                                .ConfigureAwait(false);

                            return(createdDimensionValue);
                        }
                        catch (Exception e)
                        {
                            await transaction.RollbackAsync().ConfigureAwait(false);

                            throw;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw new MasterDataBusinessLogicAddDimensionValueAsyncOperationException(e.Message, e);
            }
        }
        private void AddDimensions(KachingProduct product, Dictionary <string, ProductDefinitionField> attributePropertyMap, List <Variant> list)
        {
            foreach (var attribute in attributePropertyMap.Keys)
            {
                var flag        = false;
                var alreadyUsed = new HashSet <string>();
                foreach (var variant in list)
                {
                    if (variant.Attributes == null || variant.Attributes[attribute] == null)
                    {
                        flag = true;
                        break;
                    }
                    var value = variant.Attributes[attribute];
                    if (alreadyUsed.Contains(value))
                    {
                        flag = true;
                        break;
                    }
                    alreadyUsed.Add(value);
                }
                if (flag)
                {
                    continue;
                }
                else
                {
                    // attribute uniquely identifies each variant - use it for a dimension
                    var propertyDefinition = attributePropertyMap[attribute];
                    var dimension          = new Dimension();
                    dimension.Id     = propertyDefinition.Name;
                    dimension.Name   = Localizer.GetLocalizedName(new LocalizableProductDefinitionField(propertyDefinition));
                    dimension.Values = new List <DimensionValue>();
                    foreach (var property in propertyDefinition.DataType.DataTypeEnums)
                    {
                        var value = new DimensionValue();
                        value.Id   = property.Name;
                        value.Name = Localizer.GetLocalizedName(new LocalizableDataTypeEnum(property));
                        dimension.Values.Add(value);
                    }
                    if (dimension.Values.Count == 0)
                    {
                        // No enums defined - show values directly instead
                        var allValues = new HashSet <string>();
                        foreach (var variant in product.Variants)
                        {
                            allValues.Add(variant.Attributes[attribute]);
                        }
                        foreach (var valueString in allValues.OrderBy(a => a))
                        {
                            var value = new DimensionValue();
                            value.Id   = valueString;
                            value.Name = new L10nString(valueString);
                            dimension.Values.Add(value);
                        }
                    }

                    product.Dimensions = new List <Dimension>();
                    product.Dimensions.Add(dimension);
                    foreach (var variant in product.Variants)
                    {
                        variant.DimensionValues = new Dictionary <string, string>();
                        variant.DimensionValues[dimension.Id] = variant.Attributes[attribute];
                    }
                    break;
                }
            }
        }
        public async Task <DimensionValue> ModifyDimensionValueAsync(
            long dimensionId,
            DimensionValue oldDimensionValue,
            DimensionValue newDimensionValue)
        {
            using (MasterDataContext ctx = new MasterDataContext(_dbContextOptions))
            {
                using (IDbContextTransaction transaction = await ctx.Database.BeginTransactionAsync()
                                                           .ConfigureAwait(false))
                {
                    try
                    {
                        string dimensionIdErrorMsg = $"{nameof(dimensionId)} is zero.";
                        Check.AreNotEqual(dimensionId, 0, dimensionIdErrorMsg);

                        string oldDimensionValueErrorMsg = $"{nameof(oldDimensionValue)} is null.";
                        Check.IsNotNull(oldDimensionValue, oldDimensionValueErrorMsg);

                        string newDimensionValueErrorMsg = $"{nameof(newDimensionValue)} is null.";
                        Check.IsNotNull(newDimensionValue, newDimensionValueErrorMsg);

                        await _masterDataValidators.DimensionValueValidator.ValidateAsync(oldDimensionValue, o =>
                        {
                            o.IncludeRuleSets(ValidatorRulesets.ModifyDimensionValue);
                            o.ThrowOnFailures();
                        }).ConfigureAwait(false);

                        DomainModel.Dimension dim = await ctx.Dimensions.FindAsync(dimensionId).ConfigureAwait(false);

                        string noDimErrMsg = $"There is no dimension with id: {dimensionId}";
                        Check.IsNotNull(dim, noDimErrMsg);

                        DimensionValue dimVal = await ctx.DimensionValues.FindAsync(oldDimensionValue.Id)
                                                .ConfigureAwait(false);

                        string dimValErrMsg = $"There is no dimension value with id: {oldDimensionValue.Id}";
                        Check.IsNotNull(dimVal, dimValErrMsg);

                        // count how many dimension - dimension value relation exists
                        List <DimensionDimensionValue> countOfDimensionDimensionValueRelation = await ctx
                                                                                                .DimensionDimensionValues
                                                                                                .Where(p => p.DimensionValueId == oldDimensionValue.Id &&
                                                                                                       p.DimensionId != dimensionId)
                                                                                                .ToListAsync().ConfigureAwait(false);

                        if (countOfDimensionDimensionValueRelation.Any())
                        {
                            // If multiple dimensions references to the given dimension value
                            // then we are going to create a new dimension value and we are going to modify
                            // the dimension - dimension value reference to that
                            DimensionValue modifiedButNewDimensionValue = new DimensionValue
                            {
                                Value = newDimensionValue.Value,
                            };
                            await ctx.DimensionValues.AddAsync(modifiedButNewDimensionValue).ConfigureAwait(false);

                            await ctx.SaveChangesAsync().ConfigureAwait(false);

                            DimensionDimensionValue theOneGoingToBeModified = await ctx.DimensionDimensionValues
                                                                              .FirstOrDefaultAsync(p => p.DimensionId == dimensionId &&
                                                                                                   p.DimensionValueId == oldDimensionValue.Id)
                                                                              .ConfigureAwait(false);

                            if (theOneGoingToBeModified == null)
                            {
                                string msg = $"There is no DimensionDimensionValue entity with " +
                                             $"dimension id: {dimensionId}, and" +
                                             $"dimension value id: {oldDimensionValue.Id}!";
                                throw new MasterDataBusinessLogicNoSuchDimensionDimensionValueEntity(msg);
                            }

                            theOneGoingToBeModified.DimensionValueId = modifiedButNewDimensionValue.Id;
                            ctx.Entry(theOneGoingToBeModified).State = EntityState.Modified;
                            await ctx.SaveChangesAsync().ConfigureAwait(false);

                            await transaction.CommitAsync().ConfigureAwait(false);

                            DimensionValue modifiedResult = await ctx.DimensionValues.FirstOrDefaultAsync(
                                p => p.Id == modifiedButNewDimensionValue.Id).ConfigureAwait(false);

                            return(modifiedResult);
                        }

                        DimensionValue dimValToBeModified = await ctx.DimensionValues.FirstOrDefaultAsync(
                            p => p.Id == oldDimensionValue.Id).ConfigureAwait(false);

                        if (dimValToBeModified == null)
                        {
                            string erMsg = $"There is no dimension value with id: {oldDimensionValue.Id}";
                            throw new MasterDataBusinessLogicNoSuchDimensionValueEntity(erMsg);
                        }

                        dimValToBeModified.Value            = newDimensionValue.Value;
                        ctx.Entry(dimValToBeModified).State = EntityState.Modified;
                        await ctx.SaveChangesAsync().ConfigureAwait(false);

                        await transaction.CommitAsync().ConfigureAwait(false);

                        return(dimValToBeModified);
                    }
                    catch (Exception e)
                    {
                        await transaction.CommitAsync().ConfigureAwait(false);

                        throw new MasterDataBusinessLogicModifyDimensionValueAsyncOperationException(
                                  e.Message, e);
                    }
                }
            }
        }