【问题标题】:How to serialize an observablecollection of type entity to xml如何将类型实体的 observablecollection 序列化为 xml
【发布时间】:2017-04-20 13:31:41
【问题描述】:

我正在使用实体框架在 WPF 应用程序上使用 VS 2015。在这个应用程序中,我可以在我的一个 WPF 窗口中序列化一个画布,在该画布上我有一些自定义控件。

今天我试图向我的一个自定义控件添加一个新的依赖属性,它是一个 observablecollection,它的类型是一个实体(在我的例子中是一个名为 Formulas 的表)。

通常不可能序列化泛型类型。

所以我在我的应用中添加了一个新类,并在我的代码中使用它作为属性类型。

public class AssignedFormulasCollection : ObservableCollection<Formulas>
{
    public AssignedFormulasCollection()
    {
    }

    public AssignedFormulasCollection(List<Formulas> list) : base(list)
    {
    }
}

这是实体Formulas的代码:

public partial class Formulas
{
    public Formulas()
    {
        this.Formula_Attributes = new HashSet<Formula_Attributes>();
        this.Formula_Field_Attributes = new HashSet<Formula_Field_Attributes>();
        this.Input_Field_Formulas = new HashSet<Input_Field_Formulas>();
        this.Stepfunctions = new HashSet<Stepfunctions>();
    }

    public int formula_id { get; set; }
    public int description_id { get; set; }
    public string formula_name { get; set; }
    public string formula_version { get; set; }
    public string formula_expression { get; set; }
    public string formula_type { get; set; }
    public Nullable<float> result1 { get; set; }
    public Nullable<float> result2 { get; set; }
    public Nullable<float> result3 { get; set; }
    public Nullable<int> version { get; set; }
    public string changer { get; set; }
    public Nullable<System.DateTime> change_date { get; set; }

    public virtual Descriptions Descriptions { get; set; }
    public virtual ICollection<Formula_Attributes> Formula_Attributes { get; set; }
    public virtual ICollection<Formula_Field_Attributes> Formula_Field_Attributes { get; set; }
    public virtual ICollection<Input_Field_Formulas> Input_Field_Formulas { get; set; }
    public virtual ICollection<Stepfunctions> Stepfunctions { get; set; }
}

我通过这种方法对画布进行序列化:

public string SerializeControlToXaml(FrameworkElement element)
{
    var elementToXaml = new StringBuilder();
    var settings = new XmlWriterSettings();
    settings.Indent = true;
    settings.OmitXmlDeclaration = true;
    var serializationManager = new 
XamlDesignerSerializationManager(XmlWriter.Create(elementToXaml, settings));
    serializationManager.XamlWriterMode = XamlWriterMode.Expression;
    XamlWriter.Save(element, serializationManager);
    var xaml = elementToXaml.ToString();

    return xaml;
}

但是当我尝试使用自定义控件序列化画布时,我收到以下错误消息:

System.Reflection.TargetInvocationException 未被用户代码处理。
HResult = -2146232828
Message = System.Data.Entity.DynamicProxies.Formulas_CF5776A4E794BA378BEBDBE1E29E7967B4AACCF844AB5416006C852677145A0A 对象的 PropertyAccessorDescriptions 导致以下异常:ObjectContext 实例已被丢弃,不能再用于需要连接的事务。

来源 = 系统

堆栈跟踪:
在 System.ComponentModel.ReflectPropertyDescriptor.GetValue(对象组件)
在 System.Windows.Markup.Primitives.ElementProperty.get_Value()
在 System.Windows.Markup.Primitives.ElementPropertyBase.get_IsComposite ()
在 System.Windows.Markup.Primitives.MarkupWriter.RecordNamespaces(ScopeScope、MarkupObject 项、IValueSerializerContext 上下文、布尔 lastWasString)
在 System.Windows.Markup.Primitives.MarkupWriter.RecordNamespaces(ScopeScope、MarkupObject 项、IValueSerializerContext 上下文、布尔 lastWasString) 在 System.Windows.Markup.Primitives.MarkupWriter.RecordNamespaces(ScopeScope、MarkupObject 项、IValueSerializerContext 上下文、布尔 lastWasString) 在 System.Windows.Markup.Primitives.MarkupWriter.RecordNamespaces(ScopeScope、MarkupObject 项、IValueSerializerContext 上下文、布尔 lastWasString) 在 System.Windows.Markup.Primitives.MarkupWriter.WriteItem(MarkupObject 项) 在 System.Windows.Markup.Primitives.MarkupWriter.SaveAsXml(XmlWriter 编写器,MarkupObject 项) 在 System.Windows.Markup.Primitives.MarkupWriter.SaveAsXml(XmlWriter 编写器、Object 实例、XamlDesignerSerializationManager 管理器) 在 System.Windows.Markup.XamlWriter.Save(对象 obj,XamlDesignerSerializationManager 管理器) 在 C:\svn_checkout\P16_RoeV\Sourcen\P16Admintool_develop\P16Common\XamlDeSerializer.cs 中的 P16Common.XamlDeSerializer.SerializeControlToXaml(FrameworkElement 元素):第 50 行。 在 P16Common.CommonMethods.SerializeToXml (FrameworkElement DesignerGrid) 到 C:\svn_checkout\P16_RoeV\Sourcen\P16Admintool_develop\P16Common\CommonMethods.cs:第 61 行。 在 P16Admintool.Helper.InputMaskHelper.UpdateInputMask (InputMasksView Designerwindow) 到 C:\svn_checkout\P16_RoeV\Resources\P16Admintool_develop\P16Admintool\Helper\InputMaskHelper.cs:第 39 行。 在 C:\svn_checkout\P16_RoeV\Sourcen\P16Admintool_develop\P16Admintool\ViewModels\ChangeElementPropertiesViewModel.cs 中的 P16Admintool.ViewModels.ChangeElementPropertiesViewModel.SetElementProperties():第 152 行。 对于 C:\svn_checkout\P16_RoeV\Resources\P16Admintool_develop\P16Admintool\Views\ChangeElementProperties.xaml.cs 中的 P16Admintool.Views.ChangeElementProperties.btn_set_properties_Click (Object sender, RoutedEventArgs e):第 77 行。 在 System.Windows.RoutedEventHandlerInfo.InvokeHandler(对象目标,RoutedEventArgs routedEventArgs) 在 System.Windows.EventRoute.InvokeHandlersImpl(对象源,RoutedEventArgsArgs,布尔 reRaised) 在 System.Windows.UIElement.RaiseEventImpl(DependencyObject 发送方,RoutedEventArgs 参数) 在 System.Windows.UIElement.RaiseEvent (RoutedEventArgs e) 在 System.Windows.Controls.Primitives.ButtonBase.OnClick () 在 System.Windows.Controls.Button.OnClick () 在 System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp (MouseButtonEventArgs e) 在 System.Windows.UIElement.OnMouseLeftButtonUpThunk(对象发送方,MouseButtonEventArgs e) 在 System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(委托 genericHandler,对象 genericTarget) 在 System.Windows.RoutedEventArgs.InvokeHandler (委托处理程序,对象目标) 在 System.Windows.RoutedEventHandlerInfo.InvokeHandler(对象目标,RoutedEventArgs routedEventArgs) 在 System.Windows.EventRoute.InvokeHandlersImpl(对象源,RoutedEventArgsArgs,布尔 reRaised) 在 System.Windows.UIElement.ReRaiseEventAs(DependencyObject 发送方,RoutedEventArgs 参数,RoutedEvent newEvent) 在 System.Windows.UIElement.OnMouseUpThunk(对象发送方,MouseButtonEventArgs e) 在 System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(委托 genericHandler,对象 genericTarget) 在 System.Windows.RoutedEventArgs.InvokeHandler (委托处理程序,对象目标) 在 System.Windows.RoutedEventHandlerInfo.InvokeHandler(对象目标,RoutedEventArgs routedEventArgs) 在 System.Windows.EventRoute.InvokeHandlersImpl(对象源,RoutedEventArgsArgs,布尔 reRaised) 在 System.Windows.UIElement.RaiseEventImpl(DependencyObject 发送方,RoutedEventArgs 参数) 在 System.Windows.UIElement.RaiseTrustedEvent (RoutedEventArgs args) 在 System.Windows.UIElement.RaiseEvent(RoutedEventArgs 参数,布尔值信任) 在 System.Windows.Input.InputManager.ProcessStagingArea () 在 System.Windows.Input.InputManager.ProcessInput(InputEventArgs 输入)

【问题讨论】:

  • 您似乎缺少相关实体的急切加载。能不能也把Formulas类的代码贴出来看看?
  • 你好尤金。我添加了实体公式的代码。根据错误消息,相关实体/表描述的属性似乎存在问题。你怎么看?

标签: c# .net wpf entity-framework


【解决方案1】:

延迟加载和序列化不好混用,为什么https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx见下文。

在您的情况下,您可能需要急切地加载所有依赖项,即以下属性的集合。就像你说的那样,首先从 Descriptions 属性开始可能是个好主意。

public virtual Descriptions Descriptions { get; set; }
public virtual ICollection<Formula_Attributes> Formula_Attributes { get; set; }
public virtual ICollection<Formula_Field_Attributes> Formula_Field_Attributes { get; set; }
public virtual ICollection<Input_Field_Formulas> Input_Field_Formulas { get; set; }
public virtual ICollection<Stepfunctions> Stepfunctions { get; set; }

每当您调用上下文来加载 Formulas 时,您都需要在 Descriptions 和任何其他延迟加载的集合上调用 .Include(..)

【讨论】:

  • 谢谢尤金。同时,我尝试了一个新类,它是没有相关实体的公式的克隆。这行得通,但这意味着很多工作。
猜你喜欢
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多