How do I debug when SaveMulti says it works, but nothing happens!

Posts   
 
    
RobertPhoenix avatar
Posts: 20
Joined: 14-Aug-2006
# Posted on: 23-Jan-2010 01:09:13   

I must be missing something obvious.

I have a DataViewGrid bound to a collection. I can make a change to the grid, and it is detected in the collection. I call saveMulti, and it reports that it has saved the correct number of rows (the number that I changed), but nothing actually happens in the database.

I have put a trace on the calls to the database, and I find there are no update calls to the database (but I do see and "Audit Login", and nothing else, everytime I would expect an update statement.)

The code is very simple

                if (llbUtil.RecursiveIsDirty(vendorCosts))
                {
                    int total = vendorCosts.SaveMulti(true);
                }

My RecursiveIsDirty routine correctly tells me when something has changed on the grid. The 'total' variable reports the correct number of rows that have changes.

I don't think I need to recurse, but I tried it with the recurse overload just in case I was missing something.

I've tried putting breaks in the save routine in VendorCostEntity, but it doesn't reach that breakpoint.

I've checked whether it picks up the correct connection string by putting a break in DbUtils, and that is hit, and gets the correct string, but I can't trace any further.

Any suggestions on what I should try, and/or look at next ?

Regards,

Robert.

RobertPhoenix avatar
Posts: 20
Joined: 14-Aug-2006
# Posted on: 23-Jan-2010 01:24:04   

Having read the Guidelines ..... here is the additional information

* Post the LLBLGen Pro version + buildnr. 

Version 2.6 Final (June 6th, 2008 )

* When it's a problem occuring at runtime, post the Runtime library version.

ORMSupportClasses.Net20.dll - 2.6.8.709

* When an exception is thrown

None

* Post the template group + .NET version you're using.

SelfServicing - .NET Framework 3.5

* Post the database type and version you're using. 

SQL Server Standard Edition (64 bit) 9.00.3077.00

* Post real code. 

I got this right..

* Explain inheritance hierachies.

This is a simple collection

* If you're using custom made templates, please explain these as well. 

We have a small change in the entity template, but the code is never hit.

* Don't hijack other/old threads. 

Got this one right as well.

RobertPhoenix avatar
Posts: 20
Joined: 14-Aug-2006
# Posted on: 23-Jan-2010 02:47:17   

I haven't solved the problem yet, but I may have made some progress.

My collection was based on a view, and I understand that I have to define the primary key in the designer, which I now think I have done, although the check box in the designer could be ambiguous - it says 'Is part of primary key' - It is more than part of the primary key, it IS the primary key.

I also checked the "Is identity" and "Is readonly" checkboxes for field that is my primary key.

The problem now is that the collection that I get, which is then bound to the datagrid binding source, only contains one item, while there should be 6. But if I take the SQL produced by LLBLgen (from the trace), and put it in a SQL Server query, it certainly returns the right number of rows. So LLBLgen is making the correct query, but somehow not filling the collection correctly.

Even though I didn't get the right number of rows I find that I can now edit the Grid, and when I attempt to save, using the code in my first post, I get an exception, and the exception, when looking at the SQL produced, is because it is not picking up the right primary key value. I can verify that the collection contains the right value for the primary key by looking at the collection before it binds to the grid.

Any ideas anyone ?

Below is my code for filling the collection and binding to the datagrid binding source


    vendorCosts = new VendorCostCollection();

            //Add a Comparison
            IPredicateExpression selectFilter = new PredicateExpression();

            selectFilter.Add(new FieldCompareValuePredicate(VendorCostFields.ProductId, ComparisonOperator.Equal, productID));

            //Add a sorter
            SortExpression sorter = new SortExpression(VendorCostFields.Name | SortOperator.Ascending);

            //Get collection
            vendorCosts.GetMulti(selectFilter, 0, sorter);

            vendorCostCollectionBindingSource.DataSource = vendorCosts;

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 24-Jan-2010 20:54:19   

Hi Robert,

Could you please post the declarative aspx of your grid. Just want to see if you are putting the correct DataKeyNames on the Grid (the grid uses this property to pass the correct modified entities).

  • Is your database case sensitive collation?

  • How your view looks like? Are you doing special things on the view query?

David Elizondo | LLBLGen Support Team
RobertPhoenix avatar
Posts: 20
Joined: 14-Aug-2006
# Posted on: 25-Jan-2010 21:50:36   

I haven't done any traces in the LLBLgen code (I'll work on that), but I know SQL is being generated - as I mentioned before I can see the SQL code in my SQL Server Trace, and the problem with the SQL is that it has 1 for the ID or primary key, and that is wrong

This is a Windows Forms Application, so there is no declarative aspx. I will go back and check the DataKeyNames and make sure all is OK there. However, I did use the wizard to generate the column names and field names, so there is no possibility of a typing error.

My database collation is SQL_Latin1_General_CP1_CI_AS - which I believe is case insensitive

My view is nothing very special. It simply resolves one foreign key to the name associated with that key. I can send the exact SQL privately if you wish, but here is a simplified version

SELECT   ven.Name, pc.productCostID, pc.ProductID
FROM         dbo.ProductCosts AS pc LEFT OUTER JOIN
                      dbo.Vendors AS ven ON pc.VendorID = ven.VendorID
RobertPhoenix avatar
Posts: 20
Joined: 14-Aug-2006
# Posted on: 25-Jan-2010 22:42:49   

I turned the traces on, and also I made the primary key visible in my dataGridView.

I was then surprised to find that the primary key, instead of having the correct value, was showing "True". I checked with the entity, and sure enough the primary key was specified as a Boolean !

So then I went to the designer, and looked at the properties for that entity, even though the DB type was int for the primary key, the .Net type was shown as System.Boolean

I'm sure I never set that ! So then I saw that the Field Properties has a drop down combo box that appears to allow the user to "Use a different .NET type" - so I tried dropping that down to revert to System.Int32 - but the only option available was System.Boolean (using SD.......BooleanNumericConverter)

I tried 'Reset to default', but I'm not sure that worked (but it may have. What it doesn't do is give you any more options in the drop down list box, but it might have changed the definition. I can't be certain now)

What I did instead was to delete the entity and add it back, and sure enough it came in with System.Int32 as the .Net type, and all is now working (after regenerating and testing the application)

So I guess I only have one question left. Why does SaveMulti report that it saved x items, when in fact it didn't send any SQL to SQL Server, and never threw an exception ?

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 26-Jan-2010 04:20:47   

RobertPhoenix wrote:

So then I went to the designer, and looked at the properties for that entity, even though the DB type was int for the primary key, the .Net type was shown as System.Boolean

I'm sure I never set that ! So then I saw that the Field Properties has a drop down combo box that appears to allow the user to "Use a different .NET type" - so I tried dropping that down to revert to System.Int32 - but the only option available was System.Boolean (using SD.......BooleanNumericConverter)

I tried 'Reset to default', but I'm not sure that worked (but it may have. What it doesn't do is give you any more options in the drop down list box, but it might have changed the definition. I can't be certain now)

'Reset to default' should work and return the type to System.Int32

RobertPhoenix wrote:

What I did instead was to delete the entity and add it back, and sure enough it came in with System.Int32 as the .Net type, and all is now working (after regenerating and testing the application)

That should work too simple_smile

RobertPhoenix wrote:

So I guess I only have one question left. Why does SaveMulti report that it saved x items, when in fact it didn't send any SQL to SQL Server, and never threw an exception ?

Was 'x' the correct number of saved items in DB? Anyway, the boolean returned by SaveMulti stays for any authorization/validation rule broken during the saving process. If something else goes wrong (DB error, some validation error, etc) an exception is thrown.

David Elizondo | LLBLGen Support Team