Accessing related collection

Posts   
 
    
scotru
User
Posts: 104
Joined: 16-Feb-2006
# Posted on: 07-Mar-2017 20:39:36   

Greetings,

I have an entity "ApplicationEntity" with an optional 1-1 relation (with accessor) on another entity "RoommateGroupEntity". The RoommateGroupEntity has a 1-n relation on Roommates and a collection accessor for this relation. For data binding needs, I need direct access to the Roommates collection from the ApplicationEntity. So I added a custom accessor on ApplicationEntity like this:


        public RoommatesCollection Roommates
        {
            
           get
            {
                if (this.RoommateGroup == null)
                    return null;
                return this.RoommateGroup.Roommates;
            }
        }

However, when I load the applications and roommates like this:


            applicationsCollection1.Clear();
            IPrefetchPath prefetchPath = new PrefetchPath((int)EntityType.ApplicationsEntity);
            prefetchPath.Add(ApplicationsEntity.PrefetchPathRoommateGroup).SubPath.Add(RoommateGroupsEntity.PrefetchPathRoommates);
            applicationsCollection1.GetMulti(ApplicationsFields.TermId == termControl1.EditValue, prefetchPath);

            gridView1.RefreshData();
            gridView1.BestFitColumns();


If I break after the GetMulti call, the applicationsCollection1.Roommates is not populated for some data that has roommates and the applicationsCollection1.RoommateGroup accessor is a blank (new record).

However, if I set a break point within the Roommates accessor, I can see that the data is correct at the time the accessor is called. Somewhere inside the GetMulti call, but after my custom accessor is called, the data in the objects is being lost.

This isn't true for all elements int eh Applications collection I'm working with, but it is consistently true for a group of elements.

Any idea what might cause this or how to resolve it?

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 08-Mar-2017 06:58:13   

Hi there.

What LLBLGen version are you using?

scotru wrote:


public RoommatesCollection Roommates
        {
            
         get
            {
                if (this.RoommateGroup == null)
                    return null;
                return this.RoommateGroup.Roommates;
            }
        }

For above to work properly, please consider this (extract of the documentation):

When the related entity is not found in the database, for example Customer has an optional relation with Address using Customer.VisitingAddressID - Address.AddressID and myCustomer.VisitingAddress is accessed and myCustomer doesn't have a related visiting address entity, by default the generated code will return a new, empty entity, in this case a new AddressEntity instance.

You can then test the Fields.State value of the returned entity, if it is a new entity or a fetched entity (by comparing the Fields.State property with EntityState.New for a new entity or EntityState.Fetched for a fetched entity).

You can tell the entity to return null (C#) or Nothing (VB.NET) instead of a new entity if the entity is not found by setting the property FieldMappedOnRelationReturnNewIfNotFound to false. In our example of the Customer and its optional VisitingAddress field, mapped on the relation Customer.VisitingAddressID - Address.AddressID, Customer will have a property VisitingAddressReturnNewIfNotFound. Setting this property to false will make myCustomer.VisitingAddress return null (C#) or Nothing (VB.NET) if the related Address entity is not found for myCustomer.

By default these properties are set to true, to avoid code breakage with existing code already in production. You can change this default in the LLBLGen Pro designer: in the project settings, change the project setting, in the LLBLGen Pro Runtime Framework subsection, LazyLoadingWithoutResultReturnsNew to false and re-generate your code. The code generator will now generate 'false' / False' for all FieldMappedOnRelationReturnNewIfNotFound flags in all entities which will make sure that if an entity doesn't exist, null / Nothing is returned instead of a new entity.

Also be aware that you might be triggering lazy loading in your code, or even in your debug, when you inspect the objects. Please read the last paragraph in the documentation link I pasted above.

And last but not least, you mentioned that you don't see this behavior in all records, so please make sure that you are testing with the correct data.

David Elizondo | LLBLGen Support Team
scotru
User
Posts: 104
Joined: 16-Feb-2006
# Posted on: 08-Mar-2017 08:57:09   

Greetings,

I'm embarrassed to say with this project the version is 1.0.2005.1 Final (July 6th, 2006).

I can confirm that the related data does exist in the database--and I can see it properly loaded into the objects if I set a breakpoint in the Roommates accessor. When the code breaks within it inside the GetMulti call, the this.RoommateGroup object is properly populated and the this.Roommates returns correctly. However, at the end of the GetMulti call--this is no longer the case.

I see what you are saying about needing to modify my test in the event the RoommateGroup does not exist. But in this case, all objects in the collection have a related RoommateGroup row in the database. However, if I set a breakpoint in the line of code after the GetMulti call, I can see that not all the RoommateGroup's are correctly populated.

UPDATE: I have been able to resolve this by wrapping the GetMulti call with a BeginInit and EndInit call on my grid control (DevExpress's XtraGrid). I suspect this suspends the databinding during the GetMulti call (which is also good for performance). I am still concerned that having the Data Binding turned on would cause this issue.

scotru
User
Posts: 104
Joined: 16-Feb-2006
# Posted on: 08-Mar-2017 09:13:21   

One more observation: In this particular instance it's always the last 10 rows (of 106 total rows) where the RoommateGroup is empty after the GetMulti call when data binding is active. Clearly the problem must be related to some interaction between the grid and the LLBLGen objects--but I do wish I understood this problematic interaction better.

Could the grid be querying the Roommates accessor before the data has finished loading and thus triggering a lazy load? But if so, shouldn't the actual data be loaded rather than the empty record?

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 08-Mar-2017 17:50:31   

Isolate the source of the issue, could you please try using the vanilla (out of the box) Grid, and see if the issue still exists.

If not then it has to be the DevExpress Grid.