Modified collection does not save

Posts   
 
    
Markiemac
User
Posts: 132
Joined: 25-Apr-2006
# Posted on: 06-Dec-2007 20:36:55   

Hi, Using Adapter V2, SQL 2K, VB2005, WinForm.

I've got a modified collection which does not save. Here's what I've done.

'aBudgetDivs' is an in-memory collection filtered as EntityView2(Of BudgetDivisionEntity). It has an Identity PK.

For each row of 'aBudgetDivs' I modify field 'AppAllocID' as per the code:

                        For Each item As EntityBase2 In aBudgetDivs
                            item.Fields("AppAllocID").CurrentValue = approvalPK
                            item.IsNew = True
                        Next

I now save the modified collection using:

 approvals.SaveAllBudgetDivs(CType(aBudgetDiv, EntityCollection(Of EntityClasses.BudgetDivisionEntity)), False)

Here's the method.

    Sub SaveAllBudgetDivs(ByVal allRows As EntityCollection(Of BudgetDivisionEntity), ByVal rFetch As Boolean)
        Dim adapter As New DataAccessAdapter()
        Try
            adapter.SaveEntityCollection(allRows, rFetch, False)
        Finally
            adapter.Dispose()
        End Try
    End Sub

Nothing fancy, but nothing is saved and I can't see where I'm going wrong. Help? disappointed

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 07-Dec-2007 09:40:52   

Setting the CurrentValue doesn't flag the field as Changed, that;s why no updtae is taking place.

Why don't you use the BudgetDivisionEntity in your loop instead of the EntityBase2? Otherwise you should set the IsChanged flag to true.

Use the following:

                        For Each item As BudgetDivisionEntity In aBudgetDivs
                            item.AppAllocID = approvalPK
                            item.IsNew = True
                        Next

Or the following:

                        For Each item As EntityBase2 In aBudgetDivs
                            item.Fields("AppAllocID").CurrentValue = approvalPK
                            item.Fields("AppAllocID").IsChanged = True;
                            item.IsNew = True
                        Next

Hints: 1- Do you want to Insert new entities rather than update the existing one? that's why you are setting the IsNew field. 2- when you use the field name string, are you sure it's "AppAllocID" not "AppAllocId" with a small "d" at the end. simple_smile 3- If aBudgetDivs is an EntityView, you can use its ToEntityCollection() method to export the entities of the view into a new collection that you can modify and save afterwards.

Markiemac
User
Posts: 132
Joined: 25-Apr-2006
# Posted on: 08-Dec-2007 16:37:48   

Walaa,

Thanks for all of the above, and I now use the BudgetDivisionEntity in my loop. Unfortunately, I'm still unable to persist the modified collection because of the following exception, which is not consistent with the data in the collection.

An exception was caught during the execution of an action query: Cannot insert the value NULL into column 'FinancialYear', table 'MIS.dbo.BudgetDivision'; column does not allow nulls. INSERT fails. The statement has been terminated.. Check InnerException, QueryExecuted and Parameters of this exception to examine the cause of this exception.

At first I thought that I had failed to supply a value for field FinancialYear, but on checking the contents of the collection being passed to 'adapter.SaveEntityCollection' I could see that all fields contained appropriate data.

Interestingly, I was originally getting an exception on a different field, so I modified that db column to include a default. It now seems to be a different issue.

Its almost as if 'adapter.SaveEntityCollection' no longer has the collection passed to it.

Do you or anyone have any insights that may help me resolve this confused Thanks

Posts: 254
Joined: 16-Nov-2006
# Posted on: 08-Dec-2007 23:59:26   

If you don't understand why the INSERT is failing because the FinancialYear column your sure has a value then I would enable the LLBLGEN tracing switches.

You could enable all of them initially but I would be interested mostly in those entries for the trace switch ORMPersistenceExecution.

See "Generated code - Troubleshooting and debugging" in the help for more on setting up the trace switches and how each of them works.

Markiemac
User
Posts: 132
Joined: 25-Apr-2006
# Posted on: 09-Dec-2007 12:40:20   

Ok, will try tomorrow.

Cheers

Markiemac
User
Posts: 132
Joined: 25-Apr-2006
# Posted on: 10-Dec-2007 19:26:05   

Hi,

Have enabled Verbose Level for SqlServerDQE & ORMPersistenceExecution and am puzzled by the Sql generated for the insert. here it is:

Generated Sql query: Query: INSERT INTO [MIS].[dbo].[BudgetDivision] ([ApprovedAllocationID]) VALUES (@ApprovedAllocationID);SELECT @BudgetDivisionID=SCOPE_IDENTITY() Parameter: @BudgetDivisionID : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Output. Value: 0. Parameter: @ApprovedAllocationID : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 69.

I'm puzzled because there are 11 fields in the BudgetDivision table.

  • Field 1. PK field is BudgetDivisionID (Identity)
  • Fields 2-10 are Text, Int & Bit fields
  • Field 11. RowVer is a Timestamp field I would have expected the Generated Sql query to have specified all fields, except perhaps the Timestamp field.

All I'm actually trying to do is to Insert into the BudgetDivision table, an in-memory collection of type BudgetDivisionEntity, in which the Foreign key field 'ApprovedAllocationID' has been changed.

                    For Each item As BudgetDivisionEntity In divBudgetAllocation.allBudgetDivisions
                        item.BudgetDivisionID = Nothing
                        item.ApprovedAllocationID = approvalPK
                        item.IsNew = True
                    Next

Any ideas?

DvK
User
Posts: 323
Joined: 22-Mar-2006
# Posted on: 10-Dec-2007 22:50:25   

How are you setting the field values ? Using SetNewFieldvalue ? It looks like they're not getting set at all....

Can you check the entity.fields(x).IsChanged property ?

Markiemac
User
Posts: 132
Joined: 25-Apr-2006
# Posted on: 11-Dec-2007 00:49:13   

I'm not initially setting the field values, I fetch them.

In form A I declare Public allBudgetDivisions As EntityCollection(Of BudgetDivisionEntity) The collection is then fetched via adapter.FetchEntityCollection(budgetDivision, filter) & stored in 'allBudgetDivisions'

In form B I establish a reference to form A As a result of some user action, I modify field ApprovedAllocationID within the collection (as shown in a previous message above) I then try to Insert (not update) the modified collection using 'adapter.SaveEntityCollection'.

I get the Exception cry

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 11-Dec-2007 04:48:55   

Hi Markiemac,

You are getting the exception because for LLBLGen there aren't field values changes (coz those are just fetched, so _IsChanged _is set to false), so the update process only include those fields that have been changed.

Here the Fields.CloneAsDirty() method should be helpful:

LLBLGenPro wrote:

CloneAsDirty: Clones this object to a new EntityFields2 object where all fields are changed and the object itself is marked dirty.

Your code will look like

For Each item As EntityBase2 In aBudgetDivs
     item.Fields = item.Fields.CloneAsDirty()
     item.Fields("AppAllocID").CurrentValue = approvalPK
     item.IsNew = True
Next

This should solve your problem wink

David Elizondo | LLBLGen Support Team
Markiemac
User
Posts: 132
Joined: 25-Apr-2006
# Posted on: 11-Dec-2007 10:36:29   

YYYYYessssss it did, brilliant wink

My original For Next loop was just missing the CloneAsDirty - and despite digging myself into a hole, I did get to go where I hadn't ie. Tracing Switches.

Thansk to all smile