WP7 LINQ Delete not working - Getting NullReferenceException - linq

I'm working on a WP7 app where i need to delete a row using the DeleteOnSubmit() method, but i keep getting a NullReferenceException error. I can't find where the issue is.
public void HardDeleteOrder(int deleteOrderId)
{
var oResult = from o in App.orderDataContext.orders
where o.OrderId == deleteOrderId
select o;
foreach (var oRow in oResult)
{
App.orderDataContext.Orders.DeleteOnSubmit(oRow);
}
App.orderDataContext.SubmitChanges();
}
When i run this, the code crashes on the ending brace of the method with an exception message "NullReferenceException was unhandled".
Here's the Stack trace:
System.NullReferenceException was unhandled
Message=NullReferenceException
StackTrace:
at System.Data.Linq.Mapping.MetaAccessor`2.SetBoxedValue(Object& instance, Object value)
at System.Data.Linq.ChangeProcessor.ClearForeignKeysHelper(MetaAssociation assoc, Object trackedInstance)
at System.Data.Linq.ChangeProcessor.ClearForeignKeyReferences(TrackedObject to)
at System.Data.Linq.ChangeProcessor.PostProcessUpdates(List`1 insertedItems, List`1 deletedItems)
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges()
at orders.viewmodels.OrderViewModel.HardDeleteOrder(Int32 deleteOrderId)
at orders.OrderView.RemoveOrderFromDatabase()
at orders.OrderView.RemoveOrder()
at orders.OrderView.detailsBarCancel_Click(Object sender, EventArgs e)
at orders.App.detailsBarCancel_Click(Object sender, EventArgs e)
at Microsoft.Phone.Shell.ApplicationBarItemContainer.FireEventHandler(EventHandler handler, Object sender, EventArgs args)
at Microsoft.Phone.Shell.ApplicationBarIconButton.ClickEvent()
at Microsoft.Phone.Shell.ApplicationBarIconButtonContainer.ClickEvent()
at Microsoft.Phone.Shell.ApplicationBar.OnCommand(UInt32 idCommand)
at Microsoft.Phone.Shell.Interop.NativeCallbackInteropWrapper.OnCommand(UInt32 idCommand)
What am I missing here ?

This is mostly due to foreign key constraint.
According to
http://msdn.microsoft.com/en-us/library/bb386925.aspx
LINQ to SQL does not support or recognize cascade-delete operations. If you want to delete a row in a table that has constraints against it, you must complete either of the following tasks:
Set the ON DELETE CASCADE rule in the foreign-key constraint in the database.
Use your own code to first delete the child objects that prevent the parent object from being deleted.

Related

Xamarin.Forms android app - event handler keeping PageModel referenced despite being unsubscribed

We've got a Xamarin.Forms Android app in which we're displaying progress on a loading page, the progress value being sent by an event from another class.
We're using FreshMvvm which has ViewIsAppearing and ViewIsDisappearing overrides available in the PageModel.
So we're subscribing on ViewIsAppearing, and unsubscribing in ViewIsDisappearing - we're also unsubscribing in a PrepareForDispose method which is intended to ensure the PageModel has cleaned up so that it can be disposed.
Code is below. ProgressManager is supplied by IoC
protected override void ViewIsAppearing (object sender, EventArgs e)
{
base.ViewIsAppearing (sender, e);
ProgressManager.ProgressEvent += ProgressManager_ProgressEvent;
}
protected override void ViewIsDisappearing (object sender, EventArgs e)
{
base.ViewIsDisappearing (sender, e);
RemoveEventHandlers();
}
public override void PrepareForDispose()
{
RemoveEventHandlers();
base.PrepareForDispose();
}
private void RemoveEventHandlers()
{
ProgressManager.ProgressEvent -= ProgressManager_ProgressEvent;
}
The problem is that, when examining object in Profiler, we can see the LoadingPageModel is still in memory, because of the EventArgs created in the ViewIsAppearing (examining the "Paths To Root" in Profiler tells us this).
When I log/debug the app, I can see that RemoveEventHandlers has been called.
So is _ProgressManager.ProgressEvent -= ProgressManager_ProgressEvent;_ failing to remove the handler, or is there another reason that we've still got a reference to the PageModel from the EventArgs?
Edit One possibility is that we're subscribing more than once, but unsubscribing only once. I've checked with debug/logging, and I don't think this is the case. We're subscribing/unsubscribing symmetrically.
It turns out that we were subscribing twice (due to the lifecyle of the page in question at the start of the app lifecycle). Therefore the single unsubscribe was leaving a subscription behind.
Fixing this fixed the problem.

Windows Forms infinite loop exception

I quickly made a Windows Forms project which loads a GUI of different textboxes with float values. Some of them do have already a value initialized. All textboxes have to be updated after one of them is changed.
public Form1()
{
InitializeComponent();
initializeValues();
calculateValues();
}
public void initializeValues()
{
//textboxes are filled/initialized with default float values
}
public void calculateValues()
{
//here all textboxes are new calculated and updated
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
calculateValues();
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
calculateValues();
}
Problem:
When I execute this project, it throws me a StackOverflowException which is unhandeled (infinite loop or infinite recursion). I think it's because during the calculateValues() method the text of the textBoxes will be changed and then the Eventhandlers are activated. That's the infinite loop :-(
How I have to change my code construct above to avoid this?
Thanks.
You should not using and calling "initializeValues();" (the cause of the infinite loop).
A first solution could be to put the init value of a TextBox in InitializeComponent :
MyTextBox.Text = myInitValue;
I solved the problem by changing the Event to "KeyPress". In this case, the Event is not activated by the method itself. No more infinite loops. Setting breakpoints and step through helped me to understand "the flow". Thanks CodeCaster.

Should I trust LinqDataSource to clean up properly?

Taking my first stab as using the OnSelecting method of LinqDataSource so that I can specify a more complex query, I wrote this:
protected void CategoriesDataSource_OnSelecting(object sender, LinqDataSourceSelectEventArgs e)
{
using (DataLayerDataContext db = new DataLayerDataContext())
{
e.Result = (from feed in db.Feeds
where feed.FeedName.StartsWith("Google")
select feed.MainCategory).Distinct();
}
}
The problem, of course, is that the using clause will Dispose the DataLayerDataContext. The 'solution' is to write it without it, but I'm afraid then that the context won't be disposed of in a timely fashion, that it will leave a bunch of connections open until garbage collection runs, and so on.
I'm no expert in this area, so any comments on whether this is a real problem, or am I worried for naught?
Ah, another person burned by the unfortunate side effects of deferred loading...
protected void CategoriesDataSource_OnSelecting(object sender, LinqDataSourceSelectEventArgs e)
{
using (DataLayerDataContext db = new DataLayerDataContext())
{
e.Result = (from feed in db.Feeds
where feed.FeedName.StartsWith("Google")
select feed.MainCategory).Distinct().ToList();
// ^^^^^^^^^
}
}
This will force the DataLayerDataContext to immediately run the query and create an in-memory list that's not dependent on the context or connection. That way you get your results immediately and you can dispose the context whenever you like.
The only problem (per Steven's comment) is the lazy-loaded navigation properties; even if you force the query to evaluate, if you try to query any properties that are references to other LINQ objects (or lists of LINQ objects) they will fail to load unless you specify what properties are immediately required in the DataLoadOptions of the DataContext. See the below for an example:
protected void CategoriesDataSource_OnSelecting(object sender, LinqDataSourceSelectEventArgs e)
{
using (DataLayerDataContext db = new DataLayerDataContext())
{
DataLoadOptions loadOptions = new DataLoadOptions();
loadOptions.LoadWith<Category>(c => c.SomeReference);
loadOptions.LoadWith<Category>(c => c.SomeOtherReferences);
db.LoadOptions = loadOptions;
e.Result = (from feed in db.Feeds
where feed.FeedName.StartsWith("Google")
select feed.MainCategory).Distinct().ToList();
}
}
Once you manually specify these associations, LINQ to SQL will eagerly load them into memory when the query executes, instead of leaving them to deferred loading (which will cause an exception when the properties are used after the DataContext is disposed.)

How can I load debugging symbols for System.Windows (Windows Phone)?

The thing is, I got a weird exception from Windows Phone app I am developing:
System.Exception was unhandled
Message=Unspecified error
StackTrace:
at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
at MS.Internal.XcpImports.Collection_AddValue[T](PresentationFrameworkCollection`1 collection, CValue value)
at MS.Internal.XcpImports.Collection_AddDependencyObject[T](PresentationFrameworkCollection`1 collection, DependencyObject value)
at System.Windows.PresentationFrameworkCollection`1.AddDependencyObject(DependencyObject value)
at System.Windows.Controls.UIElementCollection.AddInternal(UIElement value)
at System.Windows.PresentationFrameworkCollection`1.Add(UIElement value)
at System.Windows.Controls.ItemsControl.AddVisualChild(Int32 index, DependencyObject container, Boolean needPrepareContainer)
at System.Windows.Controls.ItemsControl.AddContainerForPosition(GeneratorPosition position)
at System.Windows.Controls.ItemsControl.OnItemsChangedHandler(Object sender, ItemsChangedEventArgs args)
at System.Windows.Controls.ItemContainerGenerator.OnItemAdded(Object item, Int32 index)
at System.Windows.Controls.ItemContainerGenerator.System.Windows.Controls.ICollectionChangedListener.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
at System.Windows.Controls.WeakCollectionChangedListener.SourceCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.Windows.Controls.ItemCollection.NotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.Windows.Controls.ItemCollection.System.Windows.Controls.ICollectionChangedListener.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.Windows.Controls.WeakCollectionChangedListener.SourceCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.InsertItem(Int32 index, FormItem item)
at System.Collections.ObjectModel.Collection`1.Add(FormItem item)
at //My Code
What my code tried to do is add a item to an ObservableCollection.
I want to step into System.Windows code so I can see what that "Unspecified error" is.
I already do the following in my Visual Studio:
Enable .NET Framework source stepping
Enable source server support
Enable Microsoft Symbol Servers
Despite that, I can't step in (double clicking) into any of System.Windows methods in the call stack.
Any help is appreciated. Let me know if any of you need more clarification.

Telerik RadScriptManager - error while combining js files

I'm trying to combine multiple js file references using Telerik's script manager. Here is the code I have on page load:
System.Web.UI.ScriptReference jsFile1 = new System.Web.UI.ScriptReference('/virtual_folder/jsfile1.js');
System.Web.UI.ScriptReference jsFile2 = new System.Web.UI.ScriptReference('/virtual_folder/jsfile2.js');
this.Master.ScriptManager.CompositeScript.Scripts.Add(jsFile1);
this.Master.ScriptManager.CompositeScript.Scripts.Add(jsFile2);
I'm getting an error:
[NullReferenceException: Object reference not set to an instance of an object.]
System.Collections.ObjectModel.Collection`1.Add(T item) +18
Telerik.Web.UI.RadScriptManager.Page_PreRenderComplete(Object sender, EventArgs e) +95
System.EventHandler.Invoke(Object sender, EventArgs e) +0
System.Web.UI.Page.OnPreRenderComplete(EventArgs e) +8695102
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1029
What am I doing wrong?
I think that the script combining only works for embedded resources currently so you would have to embed your js Files inside a dll.
On a side note you know you can use
this.Master.ScriptManager.
tried using
RadScriptManager.GetCurrent(this)
I am assuming you are calling this from an aspx page and not an ascx control, otherwise you have to use this.Page.

Resources