SaveEntityCollection doesn't

Posts   
 
    
tmatelich
User
Posts: 95
Joined: 14-Oct-2009
# Posted on: 31-Dec-2009 01:20:20   

I can't find any documentation of it, but it seems that if I put entities to update and entities to insert in the same EntityCollection and call SaveEntityCollection, that it always doesn't save all of them.

Is this expected behavior?

I've had to do this in two places now:


   if(adapter.SaveEntityCollection(changed) != changed.Count)
   {
      foreach (ReportEntryEntity ent in changed)
      {
             if (ent.IsNew || ent.IsDirty)
            {
                  if (!adapter.SaveEntity(ent))
                       s_ILog.Debug("crap");
            }
       }
  }
daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 31-Dec-2009 02:37:11   

Please post more information about your problem. How are you inserting and updating the entities in the collection? What is your runtime library version? (http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=7717)

David Elizondo | LLBLGen Support Team
tmatelich
User
Posts: 95
Joined: 14-Oct-2009
# Posted on: 31-Dec-2009 05:39:20   

Sorry, I'd hoped for a "duh, that's how it works" or "you just have to X"

Version 2.6.9.1005 Postgresql 8.4.1 Npgsql 2.0.6

The pseudo version of what I'm doing is:


List<Entity> list; //filled by LINQ

EntityCollection<Entity> changed = new EntityCollection<Entity>();
foreach(var e in list)
{
   if(foo(e)
   {
      e.DeletedFlag = true;
      changed.Add(e);
   }
}

Entity f = changed.First().CloneEntity(); //CloneEntity is an extension method based on code found on these forums - code attached
f.DeletedFlag = false;
changed.Add(f);

//the code in the first post goes here

I haven't changed the order to see if its always the updates that go with the initial SaveEntityCollection. I also haven't tried two SaveEntityCollection's in a row.

Thanks.

Attachments
Filename File size Added on Approval
CloneHelper.cs 1,646 31-Dec-2009 05:41.13 Approved
Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 31-Dec-2009 09:37:45   

Entities inside a collection should all get saved, whether updated or inserted.

So most probably you have one or more entity which you think should have got Updated to the database, but actually no fields were changed in this entity so no updated is issued.

tmatelich
User
Posts: 95
Joined: 14-Oct-2009
# Posted on: 31-Dec-2009 16:11:13   

That is not the behavior I'm seeing, otherwise I wouldn't have added the for loop after the SaveEntityCollection, which does iterate through the collection and the new entities are still new and dirty.

In the debugger, I have looked at the elements and all are dirty.

Is there more information I can provide you short of a test app?

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 01-Jan-2010 04:11:27   

So the entity is dirty, but are the fields dirty as well? Anyway, if you can make a repro app for us would be great so we can resolve this mystery quickly.

David Elizondo | LLBLGen Support Team
tmatelich
User
Posts: 95
Joined: 14-Oct-2009
# Posted on: 04-Jan-2010 06:59:16   

Attached is the sample app, let me know if you want me to zip up the whole project and dlls.

Output I get:

I'm dirty I'm new crap entity not saved, trying again. Single save succeeded

Thanks.

Oh, didn't make a difference, but I have this in my app:

     SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2.MarkSavedEntitiesAsFetched = true; 

Testapp performs the same with it.

Attachments
Filename File size Added on Approval
Program.cs 4,434 04-Jan-2010 06:59.46 Approved
Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 04-Jan-2010 09:27:43   

To test this, we should exclude Clonning from the equation simple_smile Otherwise you'd be testing clonning as well.

So instead of this code:

//make one - copy deleted, then reset a bunch of stuff to make it NDD'y ReportEntryEntity ndd_entity = (ReportEntryEntity)delete_me.CloneEntity();

Please use the following:

         ReportEntryEntity ndd_entity = new ReportEntryEntity();
tmatelich
User
Posts: 95
Joined: 14-Oct-2009
# Posted on: 04-Jan-2010 14:40:10   

Good point, and that focuses in on the problem. When I use new ReportEntryEntity, the test passes.

So, what's different about a cloned entity from a from-scratch one? I added some printing of the PK and they are different entities.

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 04-Jan-2010 16:44:10   

So, what's different about a cloned entity from a from-scratch one? I added some printing of the PK and they are different entities.

Please make sure that ResetEntityAsNew() is called for the root entity (main entity).

tmatelich
User
Posts: 95
Joined: 14-Oct-2009
# Posted on: 04-Jan-2010 18:39:49   

I added ResetEntityAsNew(newEntity); after the for loop that calls ResetEntityAsNew() on the ordered list. It did not affect the outcome.

Remember, I'm able to successfully SaveEntity on the cloned object immediately after the failing SaveEntityCollection. I just tried calling SaveEntityCollection again instead of looping through SaveEntity, it worked. I made an extension method:


int SaveEntityCollectionWithClones(this DataAccessAdapter adapter, IEntityCollection2 collection)
{
   int num_saved=0;
   int last_num_saved = -1;
   while(num_saved < collection.Count && num_saved != last_num_saved)
   {
      last_num_saved = num_saved;
      num_saved += adapter.SaveEntityCollection(collection);
   }
   return num_saved;
}

With various extra prints, and adding a second clone, I've determined that I'm only getting one entity saved at a time, and they are progressing in index order.

How do I set up to get the Trace output?

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 05-Jan-2010 04:24:45   

tmatelich wrote:

How do I set up to get the Trace output?

This is how

David Elizondo | LLBLGen Support Team
tmatelich
User
Posts: 95
Joined: 14-Oct-2009
# Posted on: 05-Jan-2010 18:31:29   

Here's the output (attached) with


  <system.diagnostics>
    <switches>
      <add name="PostgeSqlDQE" value="4" />
      <add name="ORMGeneral" value="4" />
      <add name="ORMStateManagement" value="4" />
      <add name="ORMPersistenceExecution" value="4" />
      <add name="LinqExpressionHandler" value="4" />
    </switches>
  </system.diagnostics>

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 06-Jan-2010 06:18:50   

Interesting. I can't reproduce your problem with similar data and code over here. Apparently the first update isn't executed, seems like the new values (IsDeleted and DeletedDate) are the same, but lines below the update is executed. So, if you can prepare a database script or/and your lgp file we will try to find out what is going on with your code.

David Elizondo | LLBLGen Support Team
tmatelich
User
Posts: 95
Joined: 14-Oct-2009
# Posted on: 07-Jan-2010 21:15:23   

On a private thread, it was determined that the original and cloned entities have the same ObjectId, which causes SaveEntityCollection to only process one element at a time. I changed the CloneEntity function from http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=7568 to look like the following, and life is good.


      public static T CloneEntity<T>(this T Entity) where T: EntityBase2, new()
      {
         T newEntity = new T();

         newEntity.Fields = (IEntityFields2)CloneObject(Entity.Fields);
         ObjectGraphUtils ogu = new ObjectGraphUtils();
         List<IEntity2> flatList = ogu.ProduceTopologyOrderedList(newEntity);

         for (int f = 0; f < flatList.Count; f++)
            ResetEntityAsNew(flatList[f]);
         ResetEntityAsNew(newEntity);

         newEntity.Fields[0].ForcedCurrentValueWrite(null); //Reset the PK

         return newEntity;
      }

Barring warnings from the LLBLGen team, I assume this issue is complete.