//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

        private static void ConfigureAddedEntries(DbContext context, IGrouping <EntityState, EntityEntry> state, object[] languageKey)
        {
            int parameterPosition;

            foreach (var entry in state)
            {
                var translationEntity = TranslationConfiguration.TranslationEntities[entry.Entity.GetType().FullName];

                PersistenceHelpers.ValidateLanguageKeys(translationEntity.KeysFromLanguageEntity, languageKey);

                var translation = Activator.CreateInstance(translationEntity.Type);

                foreach (var property in entry.Entity.GetType().GetProperties())
                {
                    translationEntity.Type.GetProperty(property.Name)?.SetValue(translation, property.GetValue(entry.Entity));
                }

                parameterPosition = 0;
                foreach (var property in translationEntity.KeysFromLanguageEntity)
                {
                    context.Entry(translation).Property(property.Name).CurrentValue = languageKey[parameterPosition];
                    parameterPosition++;
                }

                foreach (var property in translationEntity.KeysFromSourceEntity)
                {
                    context.Entry(translation).Property(property.Value).CurrentValue = entry.Entity.GetType().GetProperty(property.Key).GetValue(entry.Entity);
                }

                context.Entry(translation).State = EntityState.Added;
            }
        }
Esempio n. 2
0
        internal static IQueryable <TEntity> GetTranslatedQuery <TEntity>(this IQueryable <TEntity> query, object[] desiredLanguageKey, object[] defaultLanguageKey,
                                                                          Expression <Func <TEntity, bool> > predicate = null)
            where TEntity : class
        {
            var context           = PersistenceHelpers.GetDbContext(query);
            var translationEntity = TranslationConfiguration.TranslationEntities[typeof(TEntity).FullName];

            PersistenceHelpers.ValidateLanguageKeys(translationEntity.KeysFromLanguageEntity, desiredLanguageKey, defaultLanguageKey);

            var baseQuery = context.GetType()
                            .GetMethod("Query")
                            .MakeGenericMethod(translationEntity.Type);

            var defaultTranslationQuery = (IQueryable <object>)baseQuery.Invoke(context, null);
            var desiredTranslationQuery = (IQueryable <object>)baseQuery.Invoke(context, null);

            int parameterPosition = 0;

            foreach (var property in translationEntity.KeysFromLanguageEntity)
            {
                defaultTranslationQuery = defaultTranslationQuery.Where(BuildPredicate(property.Name, defaultLanguageKey[parameterPosition]));
                desiredTranslationQuery = desiredTranslationQuery.Where(BuildPredicate(property.Name, desiredLanguageKey[parameterPosition]));
                parameterPosition++;
            }

            var sourceKeys       = translationEntity.KeysFromSourceEntity.Select(key => key.Key);
            var relationshipKeys = translationEntity.KeysFromSourceEntity.Select(key => key.Value);

            if (predicate != null)
            {
                query = query.Where(predicate);
            }

            var wanted = query
                         //Fallback
                         .Join(
                defaultTranslationQuery,
                GetKeys <TEntity>(sourceKeys),
                GetKeys <object>(relationshipKeys),
                (Entity, Translation) => new QueryJoinHelper <TEntity> {
                Entity = Entity, Translation = Translation
            })
                         //Wanted
                         .GroupJoin(
                desiredTranslationQuery,
                GetKeysFromGroup <QueryJoinHelper <TEntity>, TEntity>(sourceKeys),
                GetKeys <object>(relationshipKeys),
                (Base, Translation) => new { Base, Translation })
                         .SelectMany(result => result.Translation.DefaultIfEmpty(),
                                     (From, Translation) => From.Base.Entity.SetTranslatedProperties(Translation ?? From.Base.Translation));

            return(wanted);
        }
        //■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

        private static void ConfigureModifiedEntries(DbContext context, IGrouping <EntityState, EntityEntry> state, object[] languageKey)
        {
            int parameterPosition;

            foreach (var entry in state)
            {
                var translationEntity = TranslationConfiguration.TranslationEntities[entry.Entity.GetType().FullName];

                PersistenceHelpers.ValidateLanguageKeys(translationEntity.KeysFromLanguageEntity, languageKey);

                var translatedEntry = context.ChangeTracker.Entries().Where(e =>
                {
                    if (e.Entity.GetType() != translationEntity.Type)
                    {
                        return(false);
                    }

                    parameterPosition = 0;
                    foreach (var property in translationEntity.KeysFromLanguageEntity)
                    {
                        if (!e.Property(property.Name).CurrentValue.Equals(languageKey[parameterPosition]))
                        {
                            return(false);
                        }
                    }

                    foreach (var property in translationEntity.KeysFromSourceEntity)
                    {
                        if (!e.Property(property.Value).CurrentValue.Equals(entry.Property(property.Key).CurrentValue))
                        {
                            return(false);
                        }
                    }

                    return(true);
                }).SingleOrDefault();

                if (translatedEntry == null)
                {
                    throw new ArgumentNullException($"Could not find the translated entry for the {entry.Entity.GetType().Name} entry");
                }

                foreach (var property in entry.Entity.GetType().GetProperties())
                {
                    if (translationEntity.Type.GetProperty(property.Name) != null)
                    {
                        context.Entry(translatedEntry.Entity).Property(property.Name).CurrentValue = property.GetValue(entry.Entity);
                    }
                }
            }
        }
Esempio n. 4
0
        //■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

        internal static async Task <List <dynamic> > GetAllTranslationsQuery <TEntity>(this IQueryable <TEntity> query, CancellationToken cancellationToken = default)
            where TEntity : class
        {
            var context           = PersistenceHelpers.GetDbContext(query);
            var translationEntity = TranslationConfiguration.TranslationEntities[typeof(TEntity).FullName];

            var ingredients = await query.ToListAsync(cancellationToken);

            var sourceKeys       = translationEntity.KeysFromSourceEntity.Select(key => key.Key);
            var relationshipKeys = translationEntity.KeysFromSourceEntity.Select(key => key.Value);

            var ingredientsTranslations = await query
                                          .Join(
                context.GetType().GetMethod("Query").MakeGenericMethod(translationEntity.Type).Invoke(context, null) as IQueryable <object>,
                GetKeys <TEntity>(sourceKeys),
                GetKeys <object>(relationshipKeys),
                (Entity, Translation) => Translation)
                                          .ToListAsync(cancellationToken);

            var translatedIngredients = new List <dynamic>();

            foreach (var ingredient in ingredients)
            {
                IDictionary <string, object> ingredientMapping = new ExpandoObject();

                foreach (var property in typeof(TEntity).GetProperties())
                {
                    if (translationEntity.Type.GetProperty(property.Name) != null)
                    {
                        var translations = new Dictionary <object, string>();

                        var currentIngredientTranslations = ingredientsTranslations.AsQueryable();
                        foreach (var keyFromSource in translationEntity.KeysFromSourceEntity)
                        {
                            currentIngredientTranslations = currentIngredientTranslations
                                                            .Where(translation => context
                                                                   .Entry(translation)
                                                                   .Property(keyFromSource.Value).CurrentValue
                                                                   .Equals(ingredient.GetType().GetProperty(keyFromSource.Key).GetValue(ingredient)));
                        }

                        foreach (var translation in currentIngredientTranslations)
                        {
                            var languageKey = new Dictionary <string, object>();

                            foreach (var languageProperty in translationEntity.KeysFromLanguageEntity)
                            {
                                languageKey.Add(languageProperty.Name, context.Entry(translation).Property(languageProperty.Name).CurrentValue);
                            }

                            if (languageKey.Count == 1)
                            {
                                translations.Add(languageKey.First().Value, translation.GetType().GetProperty(property.Name).GetValue(translation) as string);
                            }
                            else
                            {
                                translations.Add(languageKey, translation.GetType().GetProperty(property.Name).GetValue(translation) as string);
                            }
                        }

                        ingredientMapping.Add($"{property.Name}Translations", translations);
                    }
                    else
                    {
                        ingredientMapping.Add(property.Name, property.GetValue(ingredient));
                    }
                }

                translatedIngredients.Add(ingredientMapping);
            }

            return(translatedIngredients);
        }
Esempio n. 5
0
        //═════════════════════════════════════════════════════════════════════════════════════════

        public static void UpsertTranslationRange <TEntity>([NotNull] this IQueryable <TEntity> source, TEntity entity, params Translation <TEntity>[] translationEntities)
            where TEntity : class
        {
            int parameterPosition;
            var context           = PersistenceHelpers.GetDbContext(source);
            var translationEntity = TranslationConfiguration.TranslationEntities[typeof(TEntity).FullName];
            var method            = getExistingTranslationsMethod.MakeGenericMethod(typeof(TEntity), translationEntity.Type);
            IEnumerable <IDictionary <string, object> > existingTranslations = null;

            PersistenceHelpers.ValidateLanguageKeys(translationEntity.KeysFromLanguageEntity, translationEntities.SelectMany(translation => translation.LanguageKey).ToArray());

            foreach (var entry in translationEntities)
            {
                var translation   = Activator.CreateInstance(translationEntity.Type);
                var trackedEntity = context.ChangeTracker.Entries().Where(entry => entry.Entity.GetType() == translationEntity.Type);

                foreach (var property in entry.Entity.GetType().GetProperties())
                {
                    translationEntity.Type.GetProperty(property.Name)?.SetValue(translation, property.GetValue(entry.Entity));
                }

                parameterPosition = 0;
                foreach (var property in translationEntity.KeysFromLanguageEntity)
                {
                    context.Entry(translation).Property(property.Name).CurrentValue = entry.LanguageKey[parameterPosition];
                    trackedEntity = trackedEntity.Where(entry => entry.Property(property.Name).CurrentValue.Equals(context.Entry(translation).Property(property.Name).CurrentValue));
                    parameterPosition++;
                }

                foreach (var property in translationEntity.KeysFromSourceEntity)
                {
                    context.Entry(translation).Property(property.Value).CurrentValue = entity.GetType().GetProperty(property.Key).GetValue(entity);
                    trackedEntity = trackedEntity.Where(entry => entry.Property(property.Value).CurrentValue.Equals(context.Entry(translation).Property(property.Value).CurrentValue));
                }

                var tracked = trackedEntity.SingleOrDefault();
                if (tracked != null)
                {
                    foreach (var property in tracked.Entity.GetType().GetProperties()
                             .Where(property => !translationEntity.KeysFromLanguageEntity.Select(key => key.Name).Contains(property.Name) ||
                                    !translationEntity.KeysFromSourceEntity.Select(key => key.Value).Contains(property.Name)))
                    {
                        tracked.Property(property.Name).CurrentValue = context.Entry(translation).Property(property.Name).CurrentValue;
                    }
                }
                else
                {
                    existingTranslations ??= ((IEnumerable <IDictionary <string, object> >)method.Invoke(null, new object[] { context, entity, translationEntity, translationEntities })).ToList();

                    var existingTranslation = existingTranslations.AsQueryable();
                    foreach (var property in context.Entry(translation).Properties
                             .Where(property => translationEntity.KeysFromLanguageEntity.Select(key => key.Name).Contains(property.Metadata.Name) ||
                                    translationEntity.KeysFromSourceEntity.Select(key => key.Value).Contains(property.Metadata.Name)))
                    {
                        existingTranslation = existingTranslation.Where(translation => translation[property.Metadata.Name].Equals(property.CurrentValue));
                    }

                    if (existingTranslation.Count() > 0)
                    {
                        context.Entry(translation).State = EntityState.Modified;
                    }
                    else
                    {
                        context.Entry(translation).State = EntityState.Added;
                    }
                }
            }
        }