StrataFrame Forum

Error when programmatically adding a new business object link record

http://forum.strataframe.net/Topic11650.aspx

By PeterA - 9/24/2007

I'm obviously missing something, but I can't seem to add a record to a business object programmatically. I have the following code segment:





ContactRoleLink.PrimaryKeyIsAutoIncremented = false;

ContactRoleLink.NewRow();

ContactRoleLink["ID_CON"] = aContactId;

ContactRoleLink["ID_RL"] = Int32.Parse(ctlDropDown.SelectedValue);

ContactRoleLink["IND_STS"] = ctlRadio.SelectedValue;

ContactRoleLink.Save(true, "ContactRoleUpdate");





When it attempts to access the ID_CON attribute, I get a business layer exception that there is no current row. I've also tried calling the Add() method after creating the new row and calling the Add() method instead of creating a new row. Both blow up at the same location.



I do realize there are flags in the Business Layer Link Manager (BLLM) object that indicate a link row should be added when a new row is added to table 2, however because of the way this page is constructed and this particular relationship, it's not an option. It does, however seem to be related to the BLLM object. I'm able to add a link programmatically to a different link business object using the same code as above (with a different link object substituted for ContactRoleLink).



I'm going to bring up the subject of documentation again because it's something that would be very helpful in determining exactly what one should do. Simple examples can only go so far, especially when trying to figure out how to implement something like the BLLM -- it's really useful, but only if I know how it will be affected by my changes and seems even more relevant now that I believe I've tracked the source of my problem to something having to do with the BLLM.
By PeterA - 9/24/2007

Sorry, I should have double-checked my code segment before I posted that. Here's an updated one:





ContactRoleLink.PrimaryKeyIsAutoIncremented = false;

ContactRoleLink.Add();

ContactRoleLink.ID_CON = aContactId;

ContactRoleLink.ID_RL = Int32.Parse(ctlDropDown.SelectedValue);

ContactRoleLink.IND_STS = ctlRadio.SelectedValue;

ContactRoleLink.Save(true, "ContactRoleUpdate");





I still get the same error. Also, here's the stack trace that I pulled from my log files:





at MicroFour.StrataFrame.Business.BusinessLayerLinkManager.HandleTableLinkSetDefaultValues()

at MicroFour.StrataFrame.Business.BusinessLayer.SetDefaultValuesEventHandler.Invoke()

at MicroFour.StrataFrame.Business.BusinessLayer.raise_SetDefaultValues()

at MicroFour.StrataFrame.Business.BusinessLayer.OnSetDefaultValues()

at MicroFour.StrataFrame.Business.BusinessLayer.NewRow()

at MicroFour.StrataFrame.Business.BusinessLayer.Add(Boolean CheckSecurity)

at MicroFour.StrataFrame.Business.BusinessLayer.Add()

at Payless.Sourcing.MaterialsManagement.EditSuppliers.SaveContactRoles(Int32 aContactId) in I:\PSS Design\Visual Studio\Materials Management\MM_UI\Suppliers\edit.aspx.cs:line 384





And the actual exception message:





BUSINESS LAYER EXCEPTION: An error occurred while setting the appropriate values on the new TableLink row.

INNER EXCEPTION: Index 0 is either negative or above rows count.

By Trent L. Taylor - 9/24/2007

Have you tried setting debug mode on so you can see what it being sent out?

MicroFour.StrataFrame.Data.DataBasics.DataSources("").SetDebugOn("c:\temp\myoutput.html",True)

This will give you everything, including the connection information.  This is a great tool when you start having "save" issues.  In 99.9% of the cases it is either data, a missing parm, etc.

By PeterA - 9/25/2007

Yes, and it doesn't get the point of trying to run an insert query on the business object I'm having trouble with. It blows up prior to even that point. After I click save, it tries inserting the contact record twice (and appears to be successful, though they both disappear when I roll back the transaction) -- not sure what's happening there either. After it inserts the link between supplier, and the link to the new contact (the programmatic new record that does work), it goes into a series of queries associated with a normal page load when moving through contact records.



I can e-mail the log if you'd like to see it.



Thanks!
By Trent L. Taylor - 9/25/2007

It sounds like there is more than one handler handling the same event.  Is there anyway that you could provide a quick sample?  Seeing it first hand may speed the process of a resolution.  Thanks. Smile
By PeterA - 9/25/2007

I might be able to set up a Webex meeting (basically you would be able to view my desktop remotely and we could speak over the phone) through our telecommunications team. Unfortunately, I really can't post much more from the software to the forums than I have because of company policies.



Would the Webex meeting be a possibility?



Thanks!
By StrataFrame Team - 9/26/2007

From looking at the exception details, the BLLM is trying to set the Foreign Key on your link table to match the current row in the two tables on the ends of the relationship.  So, when you add the new row, if there isn't a record in both Table1 and Table2, then it won't be able to pull the PKs from them for TableLink.FK1 and TableLink.FK2.  So, make sure you have visible records in both Table1 and Table2 and that they are both pointing to the correct records that should be linked by the new record in TableLink.
By PeterA - 9/26/2007

I tried what you suggested and I'm having no luck. I'm not sure the link is being removed when I tell it to.



Prior to creating the new records, I remove the BLLM instance that controls the link. It doesn't appear this is taking place, though because it still filters the role BO even after I explicitly try to fill it (I'm only seeing one record populated in there). Here's the basic flow of the method where I'm getting the problem:



1) Fills the link table and filters it according to the current row in table 1 (contact)

2) Removes the BLLM instance with Global.BllManager.Remove("ContactRole")

3) Fills the role BO with everything from the role table in the database

4) For each record in the link, it deletes the existing link

5) Adds the specified existing links, saving through each iteration of the loop (there's a maximum of three, so there are three statically named controls that are accessed via the FindControl method and their values extracted for use in adding the new link record)



These are the initial settings for the link between business objects:





Global.BllManager["ContactRole"].SyncTable1OnLinkNavigate = false;

Global.BllManager["ContactRole"].FilterTable1OnLinkFilter = LinkManagerFilterTypeOptions.None;

Global.BllManager["ContactRole"].FillTable1OnLinkFill = false;

Global.BllManager["ContactRole"].CheckTable1OnLinkAutoFill = false;



Global.BllManager["ContactRole"].SyncLinkOnTable1Navigate = false;

Global.BllManager["ContactRole"].FillLinkOnTable1Fill = false;

Global.BllManager["ContactRole"].FillLinkOnTable2Fill = false;



Global.BllManager["ContactRole"].FilterTable2OnLinkFilter = LinkManagerFilterTypeOptions.None;

Global.BllManager["ContactRole"].FillTable2OnLinkFill = true;

Global.BllManager["ContactRole"].CheckTable2OnLinkAutoFill = false;

Global.BllManager["ContactRole"].SyncTable2OnLinkNavigate = false;





I did try changing the FillTable2OnLinkFill to false and I ended up in an infinite loop. Watched my debug file get really big, really quick. BigGrin



Shouldn't it be ignoring this link since I removed it after I populated my objects or is it still persisting somehow and being implemented when I try to add a new row?
By PeterA - 10/2/2007

Any info on my question from the previous post?



"Shouldn't it be ignoring this link since I removed it after I populated my objects or is it still persisting somehow and being implemented when I try to add a new row?"



Thanks!
By StrataFrame Team - 10/2/2007

Are you doing anything within the Global.BllManager.Remove("ContactRole") to unset the business objects on the Table1 Table2 and TableLink properties?  If you aren't then even though the object is removed, it still has references to the business objects and it still has handlers on the business object events to tell it to fill/filter again.
By PeterA - 10/2/2007

Ben Chase (10/02/2007)
Are you doing anything within the Global.BllManager.Remove("ContactRole") to unset the business objects on the Table1 Table2 and TableLink properties? If you aren't then even though the object is removed, it still has references to the business objects and it still has handlers on the business object events to tell it to fill/filter again.




No, I was just calling a remove. I thought that would do the equivalent of unsetting the attributes. Would setting the Table1, Table2, and TableLink properties to null be sufficient?



Thanks!
By PeterA - 10/4/2007

Well, I've got it working now. Here's my learnings:



1) Don't use the BLLM to manage a fixed M2M relationship (i.e. three controls or sets of controls that add an M2M relationship when they contain values).

2) Always run a save after making a call to DeleteCurrentRow() on a business object because even if you call it with no parameters, it only marks them as deleted.

3) When you want to remove an M2M link, set Table1, Table2, and TableLink properties to null before destroying the relationship.

4) Make sure an Undo() is called any time an exception is thrown or it will cause some interesting issues when you try to add a row the next time through.

5) Make sure there's adequate documentation about an object before using it in an application.



Item #3 is definitely a bug. If you destroy the variable managing a relationship, it shouldn't longer fire any more events for the relationship.