Сериализация и десериализация CRM EntityCollection

Насколько я помню, в CRM 4 можно было извлекать EntityCollection из файла на диск и обратно. Я хотел бы сделать это как часть написания механизма резервного копирования и передачи данных для экземпляра CRM Online.

Однако это не работает правильно в CRM 2011, так как коллекция Attributes каждой сущности содержит список пустых объектов KeyValuePairOfStringObjects, а коллекция FormattedValues ​​каждой сущности содержит список пустых KeyValuePairOfStringStrings.

Поэтому имена и значения атрибутов объекта не были включены в сериализацию, однако они определенно имеют значения при просмотре в отладчике VS.

Есть ли способ программно сохранить эти коллекции в файл, чтобы их можно было позже десериализовать и использовать для восстановления данных туда, откуда они пришли, или в параллельный целевой экземпляр, например, для тестирования в автономном режиме?


person PaulR    schedule 20.06.2013    source источник
comment
Разве резервное копирование на уровне SQL не вариант?   -  person Joris Van Regemortel    schedule 20.06.2013
comment
В первую очередь он должен работать как в CRM Online, так и в помещении. Но также я хотел бы сохранить контроль над процессом с целью добавления дополнительных функций позже, разрешить пользователю выбирать, какие сущности и экземпляры сущностей перемещаются, сериализовать в удобочитаемый (и редактируемый) XML и попытаться легко десериализовать обратно в Объекты .net XRM, такие как Entity и EntityCollection.   -  person PaulR    schedule 20.06.2013
comment
А как насчет функции экспорта в Excel? Это позволит экспортировать данные в читаемый формат XML. См. crmdm.blogspot.be/2011. /04/how-to-export-data-from-crm-2011.html   -  person Joris Van Regemortel    schedule 21.06.2013
comment
Спасибо, Джорис. Я хочу сделать это программно через веб-сервис. Могу ли я использовать функцию экспорта в Excel через веб-службу CRM Online? с уважением,   -  person PaulR    schedule 08.08.2013


Ответы (2)


Вот моя версия метода сериализации, предложенного @bigtv

private string Serialize(EntityCollection records)
{
    string retVal = null;   
    using(var tw = new StringWriter())
    using (var xw = new XmlTextWriter(tw))
    {
        var ser = new DataContractSerializer(typeof(EntityCollection));
        ser.WriteObject(xw, records);
        retVal = tw.ToString();
    }
    return retVal;
}
person crisfervil    schedule 09.09.2014

У меня было точно такое же требование, чтобы сохранить необработанный ответ EntityCollection обратно из CRM FetchRequest. Я получил тот же результат, что и вы, от стандартного XmlSerializer, хитрость в том, чтобы использовать тот же сериализатор, который CRM использует под капотом.

Взгляните на класс DataContractSerializer: Справочник MSDN находится здесь

Это вспомогательный класс, который я написал:

    class Serialiser
    {
        /// <summary>
        /// The xml serialiser instance.
        /// </summary>
        private readonly DataContractSerializer dataContractSerialiser;

        /// <summary>
        /// Initializes a new instance of the <see cref="SerialiserService.Serialiser"/> class.
        /// </summary>
        /// <param name="typeToSerilaise">The type to serilaise.</param>
        public Serialiser(Type typeToSerilaise)
        {
            this.dataContractSerialiser = new DataContractSerializer(typeToSerilaise);
        }

        /// <summary>
        /// Serialises the specified candidate.
        /// </summary>
        /// <param name="candidate">The candidate.</param>
        /// <returns>A serialised representaiton of the specified candidate.</returns>
        public byte[] Serialise(object candidate)
        {
            byte[] output;

            using (var ms = new MemoryStream())
            {

                this.dataContractSerialiser.WriteObject(ms, candidate);
                var numberOfBytes = ms.Length;

                output = new byte[numberOfBytes];

                // Note: Only copy the exact stream length to avoid capturing trailing null bytes.
                Array.Copy(ms.GetBuffer(), output, numberOfBytes);
            }

            return output;
        }

        /// <summary>
        /// Deserialises the specified serialised instance.
        /// </summary>
        /// <param name="serialisedInstance">The serialised instance.</param>
        /// <returns>A deserialised instance of the specified type.</returns>
        public object Deserialise(byte[] serialisedInstance)
        {
            object output;

            using (var ms = new MemoryStream(serialisedInstance))
            using (var reader = XmlDictionaryReader.CreateTextReader(ms, new XmlDictionaryReaderQuotas()))
            {
                output = this.dataContractSerialiser.ReadObject(reader);
            }

            return output;
        }
    }

Использование:

new Serialiser(typeof(EntityCollection));

Затем вы можете прочитать или записать byte[] на диск.

person bigtv    schedule 19.03.2014