Saving and Updating Records in a Collection

Posts   
 
    
Posts: 14
Joined: 16-Mar-2007
# Posted on: 02-May-2007 13:38:44   

http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=6150&HighLight=1

I have Table A : => Enitity tblA Cols: ClientId Table B: => Entity tblB Cols: TblBId, ClientId (Fk with Tbl A) Table C: => Entity tblC Cols: tblId, clientId (FK with tbl A)

Case 1:I refered the above discussion in the forum and implemented the UOW like this to update an exiting record. My requirement is that there are chances that only TblA contains some data for a ClientId but TblB, TblC dont contain in that case, as soon as User pulls this record, he is required to enter the collection for TblB, TblC. I want to update the records in tblA and insert new records in TblB, TblC.

But by exceuting the below code: its create a new record in TblA, TblB, Tbl C which is not what i expected,

Any suggestions as what need to be done.

Case 2: Chances are that all the three tables contain data for a Clientid, in this case user can add, modify, delete records in tblB, tblC so basically corresponding to ClientId, data in TblA, TblB, tblC should be modified.

UnitOfWork2 uow = new UnitOfWork2();

            using (DataAccessAdapterBase adapter = DatabaseGeneric.AdapterFactory.CreateAdapter())
            {
                uow.AddCollectionForSave(tblA.tblB, false,true);
                uow.AddCollectionForSave(tblA.tblC, false,true);
                uow.AddForSave(tblA, false);                
                uow.Commit(adapter, true);

              }
Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 02-May-2007 15:47:31   

Would you please post the code which fetched tblA and updated it with the related collections of tblB and tblC?

If tblA was updated and it has the IsNew property set to false, it should act the way you want, with simple code like the following:

                UnitOfWork2 uow = new UnitOfWork2();            
                using (DataAccessAdapterBase adapter = DatabaseGeneric.AdapterFactory.CreateAdapter())
                {
                    uow.AddForSave(tblA, true); // recursive save to save the related collections               
                    uow.Commit(adapter, true);
                 } 
Posts: 14
Joined: 16-Mar-2007
# Posted on: 02-May-2007 15:58:02   

This method pulls the information from DB for a particular Client Id

public static EntityCollection<TblA> FetchClient(int clientId) { EntityCollection<TblA> lDetails = new EntityCollection<TblA>(new TblAFactory());

        // create a prefetch path to include all related entities
        IPrefetchPath2 prefetch = new PrefetchPath2((int)EntityType.TblA);
        prefetch.Add(TblA.PrefetchPathTblB);
        prefetch.Add(TblA.PrefetchPathTblC);

        // create a filter to filter on a related entity that ISNOT returned in the 
        // expected result set
        IRelationPredicateBucket filter = new RelationPredicateBucket();
        filter.Relations.Add(TblA.Relations.TblBUsingClientId, JoinHint.Left);
        filter.Relations.Add(TblA.Relations.TblCUsingClientId, JoinHint.Left);

                  filter.PredicateExpression.Add(ClientFields.ClientId == clientId);


        using (DataAccessAdapterBase adapter = DatabaseGeneric.AdapterFactory.CreateAdapter())
        {
            adapter.FetchEntityCollection(lDetails, filter, prefetch);
        }

        return lDetails;
    }

Here i update the entity TblA with the Collection of TblB and tblC

for (int intCt = 0; TblBColl.Count > intCt; intCt++) { cliententity.TblB.Add(TblBColl[intCt]); }

for (int intCt = 0; TblCColl.Count > intCt; intCt++) { cliententity.TblB.Add(TblBColl[intCt]); }

*********** this final call i am making to update/insert the data UnitOfWork2 uow = new UnitOfWork2();

            using (DataAccessAdapterBase adapter = DatabaseGeneric.AdapterFactory.CreateAdapter())
            {
                uow.AddCollectionForSave(tblA.tblB, false,true);
                uow.AddCollectionForSave(tblA.tblC, false,true);
                uow.AddForSave(tblA, false);                
                uow.Commit(adapter, true);

             } 
Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 02-May-2007 17:11:08   

Does the following code work?

EntityCollection<TblA> lDetails = new EntityCollection<TblA>(new TblAFactory());

        // create a prefetch path to include all related entities
        IPrefetchPath2 prefetch = new PrefetchPath2((int)EntityType.TblA);
        prefetch.Add(TblA.PrefetchPathTblB);
        prefetch.Add(TblA.PrefetchPathTblC);

        // create a filter to filter on a related entity that ISNOT returned in the 
        // expected result set
        IRelationPredicateBucket filter = new RelationPredicateBucket();
        filter.Relations.Add(TblA.Relations.TblBUsingClientId, JoinHint.Left);
        filter.Relations.Add(TblA.Relations.TblCUsingClientId, JoinHint.Left);

                 filter.PredicateExpression.Add(ClientFields.ClientId == clientId);


        using (DataAccessAdapterBase adapter = DatabaseGeneric.AdapterFactory.CreateAdapter())
        {
            adapter.FetchEntityCollection(lDetails, filter, prefetch);
        }

You don't need the following lines: filter.Relations.Add(TblA.Relations.TblBUsingClientId, JoinHint.Left); filter.Relations.Add(TblA.Relations.TblCUsingClientId, JoinHint.Left); As you are not filtering on anyfiild from these tables.

Now you are filtering on a field from another table "Client" filter.PredicateExpression.Add(ClientFields.ClientId == clientId); Then you should add a relation to this entity. Or as I understand there is a ClientId field in tblA entity, so you can simply filter on this field as follows: filter.PredicateExpression.Add(TblAFields.ClientId == clientId);

for (int intCt = 0; TblBColl.Count > intCt; intCt++) { cliententity.TblB.Add(TblBColl[intCt]); }

for (int intCt = 0; TblCColl.Count > intCt; intCt++) { cliententity.TblB.Add(TblBColl[intCt]); }

How is cliententity related to the lDetails collection from the first code snippet?

UnitOfWork2 uow = new UnitOfWork2();

            using (DataAccessAdapterBase adapter = DatabaseGeneric.AdapterFactory.CreateAdapter())
            {
                uow.AddCollectionForSave(tblA.tblB, false,true);
                uow.AddCollectionForSave(tblA.tblC, false,true);
                uow.AddForSave(tblA, false);                
                uow.Commit(adapter, true);

             } 

Would you please try the code I posted earlier?

UnitOfWork2 uow = new UnitOfWork2();            
                using (DataAccessAdapterBase adapter = DatabaseGeneric.AdapterFactory.CreateAdapter())
                {
                    uow.AddForSave(tblA, true); // recursive save to save the related collections               
                    uow.Commit(adapter, true);
                 } 
Posts: 14
Joined: 16-Mar-2007
# Posted on: 02-May-2007 17:21:45   

Does the following code work?

Yes this is being used to pull the records which is working fine..and this is just the normal fetch. This gives me the Enity for TblA with all the filtering. and its working fine. After getting the entity, i do some modifctaions and add collections into and than pass this entity to the below code

UnitOfWork2 uow = new UnitOfWork2();

            using (DataAccessAdapterBase adapter = DatabaseGeneric.AdapterFactory.CreateAdapter())
            {
                uow.AddCollectionForSave(tblA.tblB, false,true);
                uow.AddCollectionForSave(tblA.tblC, false,true);
                uow.AddForSave(tblA, false);                
                uow.Commit(adapter, true);

             } 

Since you asked me all the details i posted the code otherwise the problem just lies at UOW.

I hv tried this uow.AddForSave(tblA, false);
by setting Isnew=false for tblA.......... but the fun part is that for a client i was doing update there were already few records in tblB due to which it thrown the error.

So i am assuming when adding tblB to tblA, i need to set the Isnew=false for each of the entity for tblBCollection.

As you said for Enitity TblA that i need to set Isnew=false.....is good point in updating the records in tblA and inserting new records in tblB, TblC

But if tblB, C already has few records and user wants to modify...for that i think i need to loop through each enitity in tblBCollection and C Collection and set the IsNew=false, that it will just update the record otherwise insert a new record.

what do u say

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 03-May-2007 10:38:30   

So i am assuming when adding tblB to tblA, i need to set the Isnew=false for each of the entity for tblBCollection.

As you said for Enitity TblA that i need to set Isnew=false.....is good point in updating the records in tblA and inserting new records in tblB, TblC

But if tblB, C already has few records and user wants to modify...for that i think i need to loop through each enitity in tblBCollection and C Collection and set the IsNew=false, that it will just update the record otherwise insert a new record.

what do u say

For tblB and tblC entities if we have some entities fetched from the database in an earlier stage, plus any new ones you just created, the IsNew flag would be already set to false for those pre-existed entities that were fetched from the database, and would be already set to true for any new ones you create in code, so you don't need to do any loops. Just call the Save method.