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

        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;
            }
        }
예제 #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);
                    }
                }
            }
        }
예제 #4
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;
                    }
                }
            }
        }