如何将 XML 文档映射到 entity framework 对象?
How to map XML document to entity framework object?
我有以下 entity framework 对象:
namespace Proj.Accounting.Entity
{
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
public partial class DocumentStatus
{
public DocumentStatus()
{
this.Documents = new HashSet<Document>();
this.DocumentsTrackings = new HashSet<DocumentsTracking>();
this.DocumentsTrackingChildDocuments = new HashSet<DocumentsTrackingChildDocument>();
}
[XmlElement("StateId")]
public int StateId { get; set; }
[XmlElement("StateName")]
public string StateName { get; set; }
[XmlElement("GroupId")]
public Nullable<int> GroupId { get; set; }
public virtual ICollection<Document> Documents { get; set; }
public virtual ICollection<DocumentsTracking> DocumentsTrackings { get; set; }
public virtual ICollection<DocumentsTrackingChildDocument> DocumentsTrackingChildDocuments { get; set; }
}
}
我按照 class 将实体映射到 xml 字段(不是那样工作的):
using System;
using System.Collections;
using System.IO;
using System.Xml.Serialization;
namespace Proj.Accounting.Data
{
class XMLObjects
{
public static T ConvertXmlToClass<T>(string xml)
{
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(new StringReader(xml));
}
}
}
以及我用来映射数据的方法:
private void button1_Click(object sender, EventArgs e)
{
string xml = "";
xml += "<?xml version=\"1.0\" encoding=\"UTF - 8\"?>";
xml += "<root>";
xml += " <success>true</success>";
xml += " <data>";
xml += " <item>";
xml += " <StateId>0</StateId>";
xml += " <StateName>Шаблон</StateName>";
xml += " <GroupId>0</GroupId>";
xml += " </item>";
xml += "</root>";
DocumentStatus documentStatus = new DocumentStatus();
documentStatus = XMLObjects.ConvertXmlToClass<DocumentStatus>(xml);
int a = 0;
}
我遇到以下异常
System.InvalidOperationException was unhandled HResult=-2146233079
Message=There was an error reflecting type 'Proj.Accounting.Entity.DocumentStatus'. Source=System.Xml
StackTrace:
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type)
at Proj.Accounting.Data.XMLObjects.ConvertXmlToClass[T](String xml) in c:\Users\username\Dropbox\Dev\Proj.Accounting\Proj.Accounting.Data\XMLObjects.cs:line 12
at Proj.Accounting.Data.MainForm.button1_Click(Object sender, EventArgs e) in c:\Users\username\Dropbox\Dev\Proj.Accounting\Proj.Accounting.Data\MainForm.cs:line 36
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at Proj.Accounting.Data.Program.Main() in c:\Users\username\Dropbox\Dev\Proj.Accounting\Proj.Accounting.Data\Program.cs:line 19
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart() InnerException: System.InvalidOperationException HResult=-2146233079
Message=Cannot serialize member 'Proj.Accounting.Entity.DocumentStatus.Documents' of type 'System.Collections.Generic.ICollection`1[[Proj.Accounting.Entity.Document,
Proj.Accounting.Entity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]', see inner exception for more details.
Source=System.Xml
StackTrace:
at System.Xml.Serialization.StructModel.CheckSupportedMember(TypeDesc typeDesc, MemberInfo member, Type type)
at System.Xml.Serialization.StructModel.GetPropertyModel(PropertyInfo propertyInfo)
at System.Xml.Serialization.StructModel.GetFieldModel(MemberInfo memberInfo)
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
InnerException: System.NotSupportedException
HResult=-2146233067
Message=Cannot serialize member Proj.Accounting.Entity.DocumentStatus.Documents of type
System.Collections.Generic.ICollection`1[[Proj.Accounting.Entity.Document,
Proj.Accounting.Entity, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null]] because it is an interface.
InnerException:
可序列化
我认为问题在于您的 class 文档不可序列化。当您序列化一个对象时,它们的所有字段也必须是可序列化的。如果不想序列化Documents成员,就用[System.Xml.Serialization.XmlIgnoreAttribute]
标记
要将对象序列化为 XML,请使用序列化方法,反序列化请使用反序列化方法。你不需要更多。
更多信息:https://msdn.microsoft.com/es-es/library/system.xml.serialization.xmlserializer(v=vs.110).aspx
小贴士
此外,将您的字符串连接更改为使用 StringBuilder。如果这是测试代码,请记住您可以在字符串上使用 += 运算符,这会产生 Clean Code。
示例:
string xml = "";
xml = xml + "<?xml version=\"1.0\" encoding=\"UTF - 8\"?>";
xml = xml + "<root>";
使用 += 运算符(结果相同但更清晰)
string xml = "";
xml += "<?xml version=\"1.0\" encoding=\"UTF - 8\"?>";
xml += "<root>";
使用 StringBuilder(最好最快的方法)
StringBuilder xml = new StringBuilder();
xml.Append("<?xml version=\"1.0\" encoding=\"UTF - 8\"?>");
xml.Append("<root>");
一切尽在 :
Cannot serialize member
Proj.Accounting.Entity.DocumentStatus.Documents of type
System.Collections.Generic.ICollection1[[Proj.Accounting.Entity.Document,
Proj.Accounting.Entity, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null]] because it is an interface
接口不可序列化。将所有 ICollection
属性转换为类型 HashSet
以启用这些项目的序列化。
我有以下 entity framework 对象:
namespace Proj.Accounting.Entity
{
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
public partial class DocumentStatus
{
public DocumentStatus()
{
this.Documents = new HashSet<Document>();
this.DocumentsTrackings = new HashSet<DocumentsTracking>();
this.DocumentsTrackingChildDocuments = new HashSet<DocumentsTrackingChildDocument>();
}
[XmlElement("StateId")]
public int StateId { get; set; }
[XmlElement("StateName")]
public string StateName { get; set; }
[XmlElement("GroupId")]
public Nullable<int> GroupId { get; set; }
public virtual ICollection<Document> Documents { get; set; }
public virtual ICollection<DocumentsTracking> DocumentsTrackings { get; set; }
public virtual ICollection<DocumentsTrackingChildDocument> DocumentsTrackingChildDocuments { get; set; }
}
}
我按照 class 将实体映射到 xml 字段(不是那样工作的):
using System;
using System.Collections;
using System.IO;
using System.Xml.Serialization;
namespace Proj.Accounting.Data
{
class XMLObjects
{
public static T ConvertXmlToClass<T>(string xml)
{
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(new StringReader(xml));
}
}
}
以及我用来映射数据的方法:
private void button1_Click(object sender, EventArgs e)
{
string xml = "";
xml += "<?xml version=\"1.0\" encoding=\"UTF - 8\"?>";
xml += "<root>";
xml += " <success>true</success>";
xml += " <data>";
xml += " <item>";
xml += " <StateId>0</StateId>";
xml += " <StateName>Шаблон</StateName>";
xml += " <GroupId>0</GroupId>";
xml += " </item>";
xml += "</root>";
DocumentStatus documentStatus = new DocumentStatus();
documentStatus = XMLObjects.ConvertXmlToClass<DocumentStatus>(xml);
int a = 0;
}
我遇到以下异常
System.InvalidOperationException was unhandled HResult=-2146233079 Message=There was an error reflecting type 'Proj.Accounting.Entity.DocumentStatus'. Source=System.Xml StackTrace: at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter) at System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter limiter) at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace) at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace) at System.Xml.Serialization.XmlSerializer..ctor(Type type) at Proj.Accounting.Data.XMLObjects.ConvertXmlToClass[T](String xml) in c:\Users\username\Dropbox\Dev\Proj.Accounting\Proj.Accounting.Data\XMLObjects.cs:line 12 at Proj.Accounting.Data.MainForm.button1_Click(Object sender, EventArgs e) in c:\Users\username\Dropbox\Dev\Proj.Accounting\Proj.Accounting.Data\MainForm.cs:line 36 at System.Windows.Forms.Control.OnClick(EventArgs e) at System.Windows.Forms.Button.OnClick(EventArgs e) at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ButtonBase.WndProc(Message& m) at System.Windows.Forms.Button.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.Run(Form mainForm) at Proj.Accounting.Data.Program.Main() in c:\Users\username\Dropbox\Dev\Proj.Accounting\Proj.Accounting.Data\Program.cs:line 19 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException: System.InvalidOperationException HResult=-2146233079 Message=Cannot serialize member 'Proj.Accounting.Entity.DocumentStatus.Documents' of type 'System.Collections.Generic.ICollection`1[[Proj.Accounting.Entity.Document, Proj.Accounting.Entity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]', see inner exception for more details. Source=System.Xml StackTrace: at System.Xml.Serialization.StructModel.CheckSupportedMember(TypeDesc typeDesc, MemberInfo member, Type type) at System.Xml.Serialization.StructModel.GetPropertyModel(PropertyInfo propertyInfo) at System.Xml.Serialization.StructModel.GetFieldModel(MemberInfo memberInfo) at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter) at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter) at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter) InnerException: System.NotSupportedException HResult=-2146233067 Message=Cannot serialize member Proj.Accounting.Entity.DocumentStatus.Documents of type System.Collections.Generic.ICollection`1[[Proj.Accounting.Entity.Document, Proj.Accounting.Entity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] because it is an interface. InnerException:
可序列化
我认为问题在于您的 class 文档不可序列化。当您序列化一个对象时,它们的所有字段也必须是可序列化的。如果不想序列化Documents成员,就用[System.Xml.Serialization.XmlIgnoreAttribute]
标记要将对象序列化为 XML,请使用序列化方法,反序列化请使用反序列化方法。你不需要更多。
更多信息:https://msdn.microsoft.com/es-es/library/system.xml.serialization.xmlserializer(v=vs.110).aspx
小贴士
此外,将您的字符串连接更改为使用 StringBuilder。如果这是测试代码,请记住您可以在字符串上使用 += 运算符,这会产生 Clean Code。
示例:
string xml = "";
xml = xml + "<?xml version=\"1.0\" encoding=\"UTF - 8\"?>";
xml = xml + "<root>";
使用 += 运算符(结果相同但更清晰)
string xml = "";
xml += "<?xml version=\"1.0\" encoding=\"UTF - 8\"?>";
xml += "<root>";
使用 StringBuilder(最好最快的方法)
StringBuilder xml = new StringBuilder();
xml.Append("<?xml version=\"1.0\" encoding=\"UTF - 8\"?>");
xml.Append("<root>");
一切尽在 :
Cannot serialize member Proj.Accounting.Entity.DocumentStatus.Documents of type
System.Collections.Generic.ICollection1[[Proj.Accounting.Entity.Document, Proj.Accounting.Entity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] because it is an interface
接口不可序列化。将所有 ICollection
属性转换为类型 HashSet
以启用这些项目的序列化。