Serialise&反序列化CRM EntityCollection

时间:2013-06-20 04:27:14

标签: dynamics-crm-2011 dynamics-crm dynamics-crm-online

我似乎记得在CRM 4中,您可以从磁盘上的文件中检索EntityCollection。我想这样做是为CRM Online实例编写备份机制和数据传输的一部分。

然而,这似乎在CRM 2011中无法正常工作,因为每个Entity的Attributes集合包含空KeyValuePairOfStringObjects的列表,并且每个实体的FormattedValues集合包含一个列表,如果为空KeyValuePairOfStringStrings。

因此,实体属性的名称和值未包含在序列化中,但是在VS调试器中查看时它们肯定具有值。

有没有办法我可以以编程方式将这些集合存储到文件中,以便以后可以将它们反序列化并用于将数据还原到它们来自的位置或并行目标实例,例如用于离线测试?

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:0)

我有完全相同的要求从CRM FetchRequest保存原始的EntityCollection响应。我从标准的XmlSerializer获得了与你相同的结果,诀窍是使用CRM在引擎盖下使用的相同序列化器。

查看DataContractSerializer类:MSDN reference is here

这是我最后编写的帮助类:

    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 []读取或写入磁盘。