private Dictionary <string, string> GetFieldValues(string contentName, IQPArticle article, string[] fields, bool passNullValues)
        {
            var fieldValues = article.GetType()
                              .GetProperties()
                              .Where(f => fields.Contains(f.Name))
                              .Select(f => new {
                field = MappingResolver.GetAttribute(contentName, f.Name.Replace("_ID", "")).Name,
                value = GetValue(f.GetValue(article))
            })
                              .Where(f => passNullValues || f.value != null)
                              .Distinct()
                              .ToDictionary(
                f => f.field,
                f => f.value
                );

            fieldValues[SystemColumnNames.Id]       = article.Id.ToString(CultureInfo.InvariantCulture);
            fieldValues[SystemColumnNames.Created]  = article.Created.ToString(CultureInfo.InvariantCulture);
            fieldValues[SystemColumnNames.Modified] = article.Modified.ToString(CultureInfo.InvariantCulture);

            if (article.StatusTypeId != 0)
            {
                fieldValues[SystemColumnNames.StatusTypeId] = article.StatusTypeId.ToString();
            }

            return(fieldValues);
        }
        public AttributeInfo GetInfo <Tcontent>(Expression <Func <Tcontent, object> > fieldSelector)
            where Tcontent : IQPArticle
        {
            var contentName   = typeof(Tcontent).Name;
            var expression    = (MemberExpression)fieldSelector.Body;
            var attributeName = expression.Member.Name;

            return(MappingResolver.GetAttribute(contentName, attributeName));
        }
        private void UpdateObjectStateEntries(IEnumerable <ObjectStateEntry> entries, Func <ContentInfo, ObjectStateEntry, string[]> getProperties, bool passNullValues)
        {
            foreach (var group in entries.Where(e => !e.IsRelationship).GroupBy(m => m.Entity.GetType().Name))
            {
                var contentName = group.Key;
                var content     = MappingResolver.GetContent(contentName);
                if (!content.IsVirtual)
                {
                    var items = group
                                .Where(item => item.Entity is IQPArticle)
                                .Select(item => {
                        var article     = (IQPArticle)item.Entity;
                        var properties  = getProperties(content, item);
                        var fieldValues = GetFieldValues(contentName, article, properties, passNullValues);

                        return(new
                        {
                            article,
                            fieldValues
                        });
                    })
                                .ToArray();

                    Cnn.MassUpdate(content.Id, items.Select(item => item.fieldValues), 1);

                    foreach (var item in items)
                    {
                        SyncArticle(item.article, item.fieldValues);
                    }
                }
            }

            var relations = (from e in entries
                             where e.IsRelationship
                             let entityKey = (EntityKey)e.CurrentValues[0]
                                             let relatedEntityKey = (EntityKey)e.CurrentValues[1]
                                                                    let entry = e.ObjectStateManager.GetObjectStateEntry(entityKey)
                                                                                let relatedEntry = e.ObjectStateManager.GetObjectStateEntry(relatedEntityKey)
                                                                                                   let id = ((IQPArticle)entry.Entity).Id
                                                                                                            let relatedId = ((IQPArticle)relatedEntry.Entity).Id
                                                                                                                            let attribute = MappingResolver.GetAttribute(e.EntitySet.Name)
                                                                                                                                            let item = new
            {
                Id = id,
                RelatedId = relatedId,
                ContentId = attribute.ContentId,
                Field = attribute.MappedName
            }
                             group item by item.ContentId into g
                             select new { ContentId = g.Key, Items = g.ToArray() }
                             )
                            .ToArray();

            foreach (var relation in relations)
            {
                var values = relation.Items
                             .GroupBy(r => r.Id)
                             .Select(g =>
                {
                    var d = g.GroupBy(x => x.Field).ToDictionary(x => x.Key, x => string.Join(",", x.Select(y => y.RelatedId)));
                    d[SystemColumnNames.Id] = g.Key.ToString();
                    return(d);
                })
                             .ToArray();

                Cnn.MassUpdate(relation.ContentId, values, 1);
            }
        }