0
votes

I'm working with VS 2015 on a WPF application using Entity Framework. In this application I have in one of my WPF window the possibility to serialize a canvas on which I got some custom controls.

Today I tried to add to one of my custom controls a new dependencyproperty which is an observablecollection which type is an entity (in my case a table called Formulas).

Normally it's not possible to serialize generic types.

So I added a new class to my app and used that in my code as property type.

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

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

This is the code of the entity 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; }
}

I serialize the canvas by this method:

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;
}

But when I try to serialize the canvas with the custom controls I get the following error message:

System.Reflection.TargetInvocationException was not handled by user code.
HResult = -2146232828
Message = The PropertyAccessorDescriptions for the System.Data.Entity.DynamicProxies.Formulas_CF5776A4E794BA378BEBDBE1E29E7967B4AACCF844AB5416006C852677145A0A object caused the following exception: The ObjectContext instance was discarded and can no longer be used for transactions that require a connection.

Source = System

StackTrace:
At System.ComponentModel.ReflectPropertyDescriptor.GetValue (Object component)
At System.Windows.Markup.Primitives.ElementProperty.get_Value ()
At System.Windows.Markup.Primitives.ElementPropertyBase.get_IsComposite ()
At System.Windows.Markup.Primitives.MarkupWriter.RecordNamespaces (ScopeScope, MarkupObject item, IValueSerializerContext context, Boolean lastWasString)
       At System.Windows.Markup.Primitives.MarkupWriter.RecordNamespaces (ScopeScope, MarkupObject item, IValueSerializerContext context, Boolean lastWasString)        At System.Windows.Markup.Primitives.MarkupWriter.RecordNamespaces (ScopeScope, MarkupObject item, IValueSerializerContext context, Boolean lastWasString)        At System.Windows.Markup.Primitives.MarkupWriter.RecordNamespaces (ScopeScope, MarkupObject item, IValueSerializerContext context, Boolean lastWasString)        At System.Windows.Markup.Primitives.MarkupWriter.WriteItem (MarkupObject item)        At System.Windows.Markup.Primitives.MarkupWriter.SaveAsXml (XmlWriter writer, MarkupObject item)        At System.Windows.Markup.Primitives.MarkupWriter.SaveAsXml (XmlWriter writer, Object instance, XamlDesignerSerializationManager manager)        At System.Windows.Markup.XamlWriter.Save (Object obj, XamlDesignerSerializationManager manager)        At P16Common.XamlDeSerializer.SerializeControlToXaml (FrameworkElement element) in C: \ svn_checkout \ P16_RoeV \ Sourcen \ P16Admintool_develop \ P16Common \ XamlDeSerializer.cs: Line 50.        At P16Common.CommonMethods.SerializeToXml (FrameworkElement designerGrid) to C: \ svn_checkout \ P16_RoeV \ Sourcen \ P16Admintool_develop \ P16Common \ CommonMethods.cs: Line 61.        At P16Admintool.Helper.InputMaskHelper.UpdateInputMask (InputMasksView designerwindow) to C: \ svn_checkout \ P16_RoeV \ Resources \ P16Admintool_develop \ P16Admintool \ Helper \ InputMaskHelper.cs: Line 39.        At P16Admintool.ViewModels.ChangeElementPropertiesViewModel.SetElementProperties () in C: \ svn_checkout \ P16_RoeV \ Sourcen \ P16Admintool_develop \ P16Admintool \ ViewModels \ ChangeElementPropertiesViewModel.cs: Line 152.        For P16Admintool.Views.ChangeElementProperties.btn_set_properties_Click (Object sender, RoutedEventArgs e) in C: \ svn_checkout \ P16_RoeV \ Resources \ P16Admintool_develop \ P16Admintool \ Views \ ChangeElementProperties.xaml.cs: Line 77.        At System.Windows.RoutedEventHandlerInfo.InvokeHandler (Object target, RoutedEventArgs routedEventArgs)        At System.Windows.EventRoute.InvokeHandlersImpl (Object source, RoutedEventArgsArgs, Boolean reRaised)        At System.Windows.UIElement.RaiseEventImpl (DependencyObject sender, RoutedEventArgs args)        At System.Windows.UIElement.RaiseEvent (RoutedEventArgs e)        At System.Windows.Controls.Primitives.ButtonBase.OnClick ()        At System.Windows.Controls.Button.OnClick ()        At System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp (MouseButtonEventArgs e)        At System.Windows.UIElement.OnMouseLeftButtonUpThunk (Object sender, MouseButtonEventArgs e)        At System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler (Delegate genericHandler, Object genericTarget)        At System.Windows.RoutedEventArgs.InvokeHandler (Delegate handler, Object target)        At System.Windows.RoutedEventHandlerInfo.InvokeHandler (Object target, RoutedEventArgs routedEventArgs)        At System.Windows.EventRoute.InvokeHandlersImpl (Object source, RoutedEventArgsArgs, Boolean reRaised)        At System.Windows.UIElement.ReRaiseEventAs (DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)        At System.Windows.UIElement.OnMouseUpThunk (Object sender, MouseButtonEventArgs e)        At System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler (Delegate genericHandler, Object genericTarget)        At System.Windows.RoutedEventArgs.InvokeHandler (Delegate handler, Object target)        At System.Windows.RoutedEventHandlerInfo.InvokeHandler (Object target, RoutedEventArgs routedEventArgs)        At System.Windows.EventRoute.InvokeHandlersImpl (Object source, RoutedEventArgsArgs, Boolean reRaised)        At System.Windows.UIElement.RaiseEventImpl (DependencyObject sender, RoutedEventArgs args)        At System.Windows.UIElement.RaiseTrustedEvent (RoutedEventArgs args)        At System.Windows.UIElement.RaiseEvent (RoutedEventArgs args, Boolean trusted)        At System.Windows.Input.InputManager.ProcessStagingArea ()        At System.Windows.Input.InputManager.ProcessInput (InputEventArgs input)

1
It looks like you are missing an eager loading for the related entities. Can you also post the code of the Formulas class to have a look?Eugene Komisarenko
Hello Eugene. I added the code of the entity Formulas. According to the error message there seems to be a problem with the property of the related entity/table Descriptions. What do You think?Patrick Pirzer

1 Answers

1
votes

Lazy loading and serialization do not mix well, see the following article on why https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx.

In your case you might need to eagerly load all the dependencies i.e. collections of the following properties. And like you said, it might be a good idea to start with the Descriptions property first.

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; }

Whenever you call your context to load Formulas you will need to call .Include(..) on the Descriptions and any other lazy loaded collections.