Having a problem in my current project, where in a particular form we are retrieving an entity object with several related entities and entitycollections via prefetch paths. THe retrieval works just fine, all entities and collections related to the root entity are fetched correctly. Once the root entity is fetched, we are storing it in Session so that when the user clicks the Update button (after editing various fields in the form) we grab the entity from Session and assign the form values to the respective fields in the entity and related entities. There are 2 checkbox lists on the form, whose items are selected based on the records in the 2 related entity collections that were fetched previously. The problem is that when the Update() method is called, the code loops through the checkboxlists and for each item creates a new entity, sets IsNew to false, and checks if the associated entity collection contains that entity already. Then it either adds the new entity to the collection if the listitem is selected and the entity does not already exist in the collection or it adds the entity to a temporary entitycollection that is passed into the DeleteEntityCollection() method if the item is deselected and the entity does already exist in the collection.
The problem is that after the existing entity is updated after selecting some items in the checkboxlists--in this particular test case the existing entity did not initially have any items in either entitycollection--when the entity is retrieved from Session all the related entities are there with the updated fields, but the entitycollections show up as empty. I did a couple other tests to force a refetch of the entity on each postback, but anytime I grabbed the entity from Session the entitycollections where empty. Even if I did something like this:
Code in codebehind
ApplicationController controller = new ApplicationController();
ApplicationEntity application = controller.RetrieveApplicationWithRelatedEntities(applicationId, ApplicationRelations.OtherService, ApplicationRelations.Person, ApplicationRelations.SpecialStatus);
Session["Application"] = application;
//all entities and entitycollections that are fetched along with ApplicationEntity are currently
// in the application object--verified this during debugging session
ApplicationEntity appFromSession = (ApplicationEntity)Session["Application"];
// all entities are correct in appFromSession instance, but all EntityCollection objects are now empty
Exerpt of code in ApplicationController
/// <summary>
/// Retrieves the ApplicationEntity by the specified applicationID.
/// The params collection is a array of ApplicationCollections enums that
/// are passed in to specify which related Entity/EntityCollection objects you wish to have fetched along
/// with the ApplicationEntity object.
/// </summary>
/// <param name="applicationId">ApplicationId for the application to retrieve.</param>
/// <param name="relations">ApplicationRelations enum. Specifies related entities to create prefetch paths for.</param>
/// <returns>ApplicationEntity object containing any retrieved data.</returns>
public ApplicationEntity RetrieveApplicationWithRelatedEntities(int applicationId, params ApplicationRelations[] relations)
{
DataAccessAdapter adapter = new DataAccessAdapter();
ApplicationEntity appEntity = new ApplicationEntity( applicationId );
IPrefetchPath2 prefetchPath = new PrefetchPath2( (int) EntityType.ApplicationEntity );
for ( int i = 0; i < relations.Length; i++ )
{
prefetchPath.Add( GetPrefetchPathElement( relations[ i ] ) );
}
prefetchPath.Add( ApplicationEntity.PrefetchPathPerson ).SubPath.Add( PersonEntity.PrefetchPathAddress );
adapter.FetchEntity( appEntity, prefetchPath );
return appEntity;
}
/// <summary>
/// Gets the prefetch path element for the specified ApplicationCollections enum.
/// </summary>
/// <param name="relation">ApplicationRelations enum.</param>
/// <returns>IPrefetchPathElement2 object containing the prefetch path information for the specified relation.</returns>
private IPrefetchPathElement2 GetPrefetchPathElement(ApplicationRelations relation)
{
switch ( (int) relation )
{
case (int) ApplicationRelations.ApplicationSpecialStatus:
return ApplicationEntity.PrefetchPathApplicationSpecialStatusCollection;
case (int) ApplicationRelations.ApplicationStatus:
return ApplicationEntity.PrefetchPathApplicationStatus;
case (int) ApplicationRelations.ChildRecon:
return ApplicationEntity.PrefetchPathChildReconCollection;
case (int) ApplicationRelations.CombatDeterminationDecision:
return ApplicationEntity.PrefetchPathCombatDeterminationDecision;
case (int) ApplicationRelations.CongressionalInquiry:
return ApplicationEntity.PrefetchPathCongressionalInquiryCollection;
case (int) ApplicationRelations.DfasTransmittalLetter:
return ApplicationEntity.PrefetchPathDfasTransmittalLettersCollection;
case (int) ApplicationRelations.Disability:
return ApplicationEntity.PrefetchPathDisabilityCollection;
case (int) ApplicationRelations.DocumentType:
return ApplicationEntity.PrefetchPathDocumentTypeCollection;
case (int) ApplicationRelations.IneligibleByUser:
return ApplicationEntity.PrefetchPathIneligibleByUserCollection;
case (int) ApplicationRelations.IneligibleReasons:
return ApplicationEntity.PrefetchPathIneligibileReasonsCollection;
case (int) ApplicationRelations.Inquiry:
return ApplicationEntity.PrefetchPathInquiryCollection;
case (int) ApplicationRelations.Inventory:
return ApplicationEntity.PrefetchPathInventoryCollection;
case (int) ApplicationRelations.Notification:
return ApplicationEntity.PrefetchPathNotificationCollection;
case (int) ApplicationRelations.OtherService:
return ApplicationEntity.PrefetchPathOtherServiceCollection;
case (int) ApplicationRelations.Reconsideration:
return ApplicationEntity.PrefetchPathReconCollection;
case (int) ApplicationRelations.Responsibility:
return ApplicationEntity.PrefetchPathApplicationResponsibilityCollection;
case (int) ApplicationRelations.SpecialStatus:
return ApplicationEntity.PrefetchPathSpecialStatusCollection;
case (int) ApplicationRelations.StatusHistory:
return ApplicationEntity.PrefetchPathApplicationStatusHistoryCollection;
default: // This is completely arbitrary--could have returned any collection
return ApplicationEntity.PrefetchPathApplicationSpecialStatusCollection;
;
}
}
In case you are wondering, ApplicationRelations is an enumeration I created to make it easy for a developer to fetch the entity and specify a custom set of related entities/collections to fetch along with it.
Any ideas as to what is going on?