Out of range exception when adding new entity in collection

Posts   
 
    
Barry
User
Posts: 232
Joined: 17-Aug-2005
# Posted on: 29-Mar-2007 12:22:55   

I've a Infragistics UltraGrid and LLBLGEN v2.0.7.319 libraries, the grid is data bound to a child collection of an entity via a BindingSource, when I click in the grid, and add a new row, it throw ThrowArgumentOutOfRangeException, it is very strange that it only happen on this entity type, but not others.


Member Name: Void ThrowArgumentOutOfRangeException(System.ExceptionArgument, System.ExceptionResource)
Exception: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
   at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
   at System.ThrowHelper.ThrowArgumentOutOfRangeException()
   at System.Collections.Generic.List`1.get_Item(Int32 index)
   at SD.LLBLGen.Pro.ORMSupportClasses.CollectionCore`1.get_Item(Int32 index) in C:\Program Files\Solutions Design\LLBLGen Pro v2.0\RuntimeLibraries\Sourcecode\Net2.x\ORMSupportClasses\CollectionCore.cs:line 1282
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityViewBase`1.GetEntityAtIndex(Int32 index) in C:\Program Files\Solutions Design\LLBLGen Pro v2.0\RuntimeLibraries\Sourcecode\Net2.x\ORMSupportClasses\EntityViewBase.cs:line 600
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityViewBase`1.System.Collections.IList.get_Item(Int32 index) in C:\Program Files\Solutions Design\LLBLGen Pro v2.0\RuntimeLibraries\Sourcecode\Net2.x\ORMSupportClasses\EntityViewBase.cs:line 1530
   at System.Windows.Forms.BindingSource.get_Item(Int32 index)
   at System.Windows.Forms.CurrencyManager.EndCurrentEdit()
   at System.Windows.Forms.BindingSource.EndEdit()
   at System.Windows.Forms.BindingSource.AddNew()
   at System.Windows.Forms.CurrencyManager.AddNew()

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 29-Mar-2007 12:50:16   

Is this reproducable with the MS datagridview shipped with .NET 2.0 ?

Frans Bouma | Lead developer LLBLGen Pro
Barry
User
Posts: 232
Joined: 17-Aug-2005
# Posted on: 29-Mar-2007 14:13:54   

Yes, it is reproducable with standard DataGridView


   at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
   at System.ThrowHelper.ThrowArgumentOutOfRangeException()
   at System.Collections.Generic.List`1.get_Item(Int32 index)
   at SD.LLBLGen.Pro.ORMSupportClasses.CollectionCore`1.get_Item(Int32 index) in C:\Program Files\Solutions Design\LLBLGen Pro v2.0\RuntimeLibraries\Sourcecode\Net2.x\ORMSupportClasses\CollectionCore.cs:line 1282
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityViewBase`1.GetEntityAtIndex(Int32 index) in C:\Program Files\Solutions Design\LLBLGen Pro v2.0\RuntimeLibraries\Sourcecode\Net2.x\ORMSupportClasses\EntityViewBase.cs:line 600
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityViewBase`1.System.Collections.IList.get_Item(Int32 index) in C:\Program Files\Solutions Design\LLBLGen Pro v2.0\RuntimeLibraries\Sourcecode\Net2.x\ORMSupportClasses\EntityViewBase.cs:line 1530
   at System.Windows.Forms.BindingSource.get_Item(Int32 index)
   at System.Windows.Forms.CurrencyManager.OnCurrentChanged(EventArgs e)
   at System.Windows.Forms.CurrencyManager.ChangeRecordState(Int32 newPosition, Boolean validating, Boolean endCurrentEdit, Boolean firePositionChange, Boolean pullData)
   at System.Windows.Forms.CurrencyManager.UpdateIsBinding(Boolean raiseItemChangedEvent)
   at System.Windows.Forms.CurrencyManager.UpdateIsBinding()
   at System.Windows.Forms.CurrencyManager.List_ListChanged(Object sender, ListChangedEventArgs e)
   at System.ComponentModel.ListChangedEventHandler.Invoke(Object sender, ListChangedEventArgs e)
   at System.Windows.Forms.BindingSource.OnListChanged(ListChangedEventArgs e)
   at System.Windows.Forms.BindingSource.InnerList_ListChanged(Object sender, ListChangedEventArgs e)
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityViewBase`1.OnListChanged(Int32 index, ListChangedType typeOfChange) in C:\Program Files\Solutions Design\LLBLGen Pro v2.0\RuntimeLibraries\Sourcecode\Net2.x\ORMSupportClasses\EntityViewBase.cs:line 746
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityViewBase`1.AddNew() in C:\Program Files\Solutions Design\LLBLGen Pro v2.0\RuntimeLibraries\Sourcecode\Net2.x\ORMSupportClasses\EntityViewBase.cs:line 142
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityViewBase`1.System.ComponentModel.IBindingList.AddNew() in C:\Program Files\Solutions Design\LLBLGen Pro v2.0\RuntimeLibraries\Sourcecode\Net2.x\ORMSupportClasses\EntityViewBase.cs:line 1275
   at System.Windows.Forms.BindingSource.AddNew()
   at System.Windows.Forms.CurrencyManager.AddNew()
   at System.Windows.Forms.DataGridView.DataGridViewDataConnection.AddNew()
   at System.Windows.Forms.DataGridView.DataGridViewDataConnection.OnNewRowNeeded()
   at System.Windows.Forms.DataGridView.OnRowEnter(DataGridViewCell& dataGridViewCell, Int32 columnIndex, Int32 rowIndex, Boolean canCreateNewRow, Boolean validationFailureOccurred)
   at System.Windows.Forms.DataGridView.SetCurrentCellAddressCore(Int32 columnIndex, Int32 rowIndex, Boolean setAnchorCellAddress, Boolean validateCurrentCell, Boolean throughMouseClick)
   at System.Windows.Forms.DataGridView.OnCellMouseDown(HitTestInfo hti, Boolean isShiftDown, Boolean isControlDown)
   at System.Windows.Forms.DataGridView.OnCellMouseDown(DataGridViewCellMouseEventArgs e)
   at System.Windows.Forms.DataGridView.OnMouseDown(MouseEventArgs e)
   at System.Windows.Forms.Control.WmMouseDown(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.DataGridView.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.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

I compiled LLBLGen source code and try to trace the problem, I found that exception is thrown from CollectionCore.cs, at "public T this[int index]", the index is -1, and it is called by EntityViewBase.GetEntityAtIndex(int index), _entityIndices contains an item "-1", which cause the exception. I test it with other entity types, it has a "0" in _entityIndices.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 29-Mar-2007 14:27:47   

Ok, I think we should avoid in a long discussion about does this or does that work/don't work, so if you could provide me with the entity type, the form code with teh default grid I'll try to repro it.

Important for me to know: - the collection bound to the grid, is that collection empty? - did you sort the grid? - did you filter the collection by creating a new entityview and add a filter to that and bind that view to the grid, or did you bind the collection directly? - does the entity have subtypes?

Frans Bouma | Lead developer LLBLGen Pro
Barry
User
Posts: 232
Joined: 17-Aug-2005
# Posted on: 29-Mar-2007 15:20:16   

It is a child collection of an entity, like customer -> orders, and it does not have any subtypes.

It is empty with I bind it to the grid, and the grid does not have any filtering or sorting.


CustomerEntity customer = new CustomerEntity();
bindingSource1.DataSource = customer;
bindingSource2.DataSource = customer.Orders;
dataGridView1.Datasource = bindingSource2;

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 29-Mar-2007 15:45:32   

Thanks, I'll see if I can cook up a repro case. simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 29-Mar-2007 18:25:46   

I can't repro it with:


// in viewer form
public void BindViaBindingSource(IEntityCollection2 toBind)
{
    BindingSource bd = new BindingSource();
    bd.DataSource = toBind;
    _theGrid.DataSource = bd;
}

//...
[Test]
public void EmptyRowInGridCrashTest()
{
    CustomerEntity c = new CustomerEntity();
    ResultsetViewer20 viewer = new ResultsetViewer20();
    viewer.BindViaBindingSource(c.Orders);
    viewer.ShowDialog(null);
}

WHen I click on the row and type in a value, I get a new entity, and it's added correctly. I can add more rows if I want to.

It even performs correctly the syncing of FK's and PK's. If I add a value in CustomerId, the row is removed, because the containing customer is empty, so the FK isn't matching. THis also doesn't repro it.

I'll now try with the 2 bindingsources you have, though I doubt it will make any difference.

Do you bind the bindingsources to something else?

(edit) I also can't repro it with two binding sources. Very strange...

Frans Bouma | Lead developer LLBLGen Pro
Barry
User
Posts: 232
Joined: 17-Aug-2005
# Posted on: 30-Mar-2007 08:11:52   

I found the problem, it' our programmer fault. He handled the EntityAdding event of the child collection, and assign value to the key fields of that new entity, which cause that entity failed to add into the collection and leading to out of range exception finally. frowning

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 30-Mar-2007 09:33:04   

Ok, glad it's sorted out simple_smile

Frans Bouma | Lead developer LLBLGen Pro