- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
Saving and Updating Records in a Collection
Joined: 16-Mar-2007
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);
}
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);
}
Joined: 16-Mar-2007
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);
}
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);
}
Joined: 16-Mar-2007
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
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.