Simple DataBinding Advice re migrating from v1.0.2005.1 to v2.0?

Posts   
 
    
Posts: 16
Joined: 22-Mar-2006
# Posted on: 15-Aug-2006 08:15:09   

I'm updating a WindowsForms app (Self Servicing using SQL Server 2005) from v1.0.2005.1 to v2.0. I have some forms which are data bound to the fields in an LLBLGen Pro entity, and which have the usual BindingSource and BindingNavigator. (These forms often don't have a grid on them, just individual data bound text fields, etc.)

In v1.0.2005.1 what worked for me was to define the "ABCEntityBindingSource_AddingNew(object sender, System.ComponentModel.AddingNewEventArgs e)" method, and have this method create a new ABCEntity and set its id (and other fields) to appropriate values, then assign it to e.NewObject. But when I run this on v2.0 and click the "Add" button in the binding navigator, I get NotSupportedException saying "Add a new object to the related collection instead, or use IBindingList.AddNew() on this object." (See below for stack trace).

After some experimentation, it looks like I may not need the ..._AddingNew() method in 2.0. Things seem to work without it, except that now I don't get a chance to set the id and other fields on the new entity, so when I later do a "Save", the id may be null. I think the correct way to solve this is to declare the id column in SQL Server to be "identity(1,1)", and in LLBLGen Pro on the Id field to set "Is Identity/Sequence field, Sequence Used SCOPE_IDENTITY()". I'm having a little trouble getting this to work correctly, as I still get exceptions that the id field is null.

What is the recommended way to do this? That is, how should I declare the id column in SQL Server, and what properties should I set on the id field in LLBLGen Pro?

Also, I have some other entities which have a composite key, consisting of an id and a version. This means that the id alone may not be unique (I could have id=1,version=1 and id=1,version=2), so I don't think I can declare id to be "identity(1,1)" for this entity.

Any advice would be much appreciated!

Thanks,

Wayne

System.NotSupportedException occurred Message="Add a new object to the related collection instead, or use IBindingList.AddNew() on this object." Source="SD.LLBLGen.Pro.ORMSupportClasses.NET20" StackTrace: at SD.LLBLGen.Pro.ORMSupportClasses.EntityViewBase`1.System.Collections.IList.Add(Object value) at System.Windows.Forms.BindingSource.Add(Object value) at System.Windows.Forms.BindingSource.AddNew() at System.Windows.Forms.BindingNavigator.OnAddNew(Object sender, EventArgs e) at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e) at System.Windows.Forms.ToolStripButton.OnClick(EventArgs e) at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e) at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e) at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met) at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met) at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ScrollableControl.WndProc(Message& m) at System.Windows.Forms.ToolStrip.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.I MsoComponentManager.FPushMessageLoop(Int32 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 DataEntry2.Program.Main() in C:\DataEntry\Program.cs:line 15

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 15-Aug-2006 09:23:20   

What is the recommended way to do this? That is, how should I declare the id column in SQL Server, and what properties should I set on the id field in LLBLGen Pro?

Using the SQL Server Enterprise Manager -> go to "yourTable->Design Table"and set the identity to true, or just use QA and ALTER the table with "IDENTITY (1, 1) NOT NULL" assigned to the PK.

Anyway you should refresh your catalog in LLBLGen Pro Designer and then check to see if the Entity's PK has the "IsIdentity/Sequence" checked, in the Entity Fields subtab of the Entity's properties dialog.

Then you should re-generate the code, and the most important part is to make sure your application is using the newly generated code/assemblies rather than the old ones.

Jessynoo avatar
Jessynoo
Support Team
Posts: 296
Joined: 19-Aug-2004
# Posted on: 15-Aug-2006 16:56:34   

Did you try adding the entity to the collection your entityview is bound to, as suggested in the message? That should allow you to set your entity as you wish.

Posts: 16
Joined: 22-Mar-2006
# Posted on: 16-Aug-2006 03:16:24   

Walaa and Jesse,

Thanks for your quick and helpful suggestions. I really appreciate it!

I set my primary keys to "identity(1,1) not null" and refreshed and generated, and now it's working OK. (I thought I'd tried this yesterday, I guess I'd left out a step...)

Jessynoo wrote:

Did you try adding the entity to the collection your entityview is bound to, as suggested in the message? That should allow you to set your entity as you wish.

I tried to do this:

private void billEntityBindingSource_AddingNew(object sender, System.ComponentModel.AddingNewEventArgs e) {
      e.NewObject = billEntityBindingSource.AddNew();
}

but I get a stack overflow because it recursively calls billEntityBindingSource_AddingNew confused

I do need to set a few fields before the record is saved, so since I couldn't get the billEntityBindingSource_AddingNew() changes to work, I added the code to the constructors in FactoryClasses/EntityFactories.cs. This seems to work OK, but of course the constructor gets called whenever a record is created, even when an existing record is read from the database. This seems harmless... I set these values to the default, then LLBLGenPro overwrites them with the real values from the database.

I'd still be very interested if you had any suggestions on how I could add the entity to the collection like the error message suggests.

Thanks,

Wayne

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 16-Aug-2006 15:01:24   

I think what you have done is correct, you can also have you data initializations in the InitClassMembers() or InitClassEmpty() pf the generated entity classes.