Working w Multiple table w exact same schema

Posts   
 
    
amccool avatar
amccool
User
Posts: 18
Joined: 08-Jun-2007
# Posted on: 08-Jun-2007 02:52:31   

Hi,

I'm looking for a suggestion to reduce some duplicated code.

The issue is, there are two tables in my database that have the exact same schema. I am constantly rewriting the exact same code to access these two tables where all I'm doing is replacing the Table1Collection/Entity with Table2Collection/Entity class names.

I'm using the self-service style. This is a legacy database, and I cant change anything about it.

Generics would seem to be the slam dunk, but the table has like 90 columns in it (both of them), so that turns into alot of code in and of itself.

Any ideas? Alex

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 08-Jun-2007 09:40:24   

I am constantly rewriting the exact same code to access these two tables where all I'm doing is replacing the Table1Collection/Entity with Table2Collection/Entity class names.

Are you speaking about databinding code? Where exactly do you suggest/want the code savings should occur?

It seems like a perfect copy and paste scenario, where the only typing would be to in the line of code where you construct the collection.

amccool avatar
amccool
User
Posts: 18
Joined: 08-Jun-2007
# Posted on: 08-Jun-2007 18:29:59   

The copy/paste scenario is really the avoidance here.

I'm looking for data out of these two table. For both tables the Predicate looks exactly the same same column names, same values, even the same relationships. Examples are best so...


         private void junk(int encounterId, int hdrId, int parentId)
        {
            TableAEncounterItemsCollection tableAItems = new TableAEncounterItemsCollection();

            IRelationCollection relations = new RelationCollection();
            relations.Add(TableAEncounterItemsEntity.Relations.LstItemsEntityUsingLListId, JoinHint.Left);

            IPredicateExpression firstselect = new PredicateExpression();
            firstselect.Add(TableAEncounterItemsFields.LEncounterId == encounterId);
            firstselect.AddWithAnd(TableAEncounterItemsFields.LListHeaderId == hdrId);
            firstselect.AddWithAnd(TableAEncounterItemsFields.LParentId == parentId);
            firstselect.AddWithAnd(TableAEncounterItemsFields.BDeletedFl == false);

            //watch out for addendums
            firstselect.AddWithAnd(TableAEncounterItemsFields.LAddendumId == 0);

            tableAItems.GetMulti(firstselect, -1, null, relations);
            foreach (TableAEncounterItemsEntity ent in tableAItems)
            {
                if (ent.SDescriptionTx == ent.LstItems.SDescriptionTx)
                {
                    return ent.DtLastUpdateDt;
                }
            }
        
        //===now the other table

            TableBEncounterItemsCollection tableBItems = new TableBEncounterItemsCollection();

            IRelationCollection relations = new RelationCollection();
            relations.Add(TableBEncounterItemsEntity.Relations.LstItemsEntityUsingLListId, JoinHint.Left);

            IPredicateExpression secondselect = new PredicateExpression();
            secondselect.Add(TableBEncounterItemsFields.LEncounterId == encounterId);
            secondselect.AddWithAnd(TableBEncounterItemsFields.LListHeaderId == hdrId);
            secondselect.AddWithAnd(TableBEncounterItemsFields.LParentId == parentId);
            secondselect.AddWithAnd(TableBEncounterItemsFields.BDeletedFl == false);

            //watch out for addendums
            secondselect.AddWithAnd(TableBEncounterItemsFields.LAddendumId == 0);


            tableBItems.GetMulti(secondselect, -1, null, relations);
            foreach (TableBEncounterItemsEntity ent in tableBItems)
            {
                if (ent.SDescriptionTx == ent.LstItems.SDescriptionTx)
                {
                    return ent.DtLastUpdateDt;
                }
            }
        
        }


Perhaps there is a different way I could do this. I have 6 different class in play here Collection, Entity, Field. Writing this with generic's would be perfect, but the

: where

clauses become nightmarish. disappointed

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 09-Jun-2007 12:51:18   

I've faced the same scenario. Although I can use Activator and write generic methods, that's a little cumbersome and finally I get a non-friendly-readable code. IMHO in some cases I recommend copy-paste approach.

David Elizondo | LLBLGen Support Team
sami
User
Posts: 93
Joined: 28-Oct-2005
# Posted on: 11-Jun-2007 10:37:57   

If you want to do it with reflection, it is not that difficult actually. I have played quite a bit with reflection using both SS and adapter patterns..

Your sample would look maybe something like this:



private void junk(IEntityCollection tableAorBItems, int encounterId, int hdrId, int parentId, string entityName)
        {           
            IRelationCollection relations = new RelationCollection();

            PropertyInfo relationsProperty = tableAorBItems.GetType().GetProperty("Relations");
            Object relationsObject = relationsProperty.GetValue(null, null);

            PropertyInfo LstItemsEntityUsingLListIdProperty = relationsObject.GetType().GetProperty("LstItemsEntityUsingLListId");
            IEntityRelation LstItemsEntityUsingLListIdValue = (IEntityRelation)LstItemsEntityUsingLListIdProperty.GetValue(null,null);

            relations.Add(LstItemsEntityUsingLListIdValue, JoinHint.Left);
        
            ObjectHandle col = Activator.CreateInstance("assemblyname", "rootnamespace.EntityClasses." + entityName);
            IEntity entity = (IEntity)col.Unwrap();

            IPredicateExpression firstselect = new PredicateExpression();

            EntityField entityField = (entity.Fields["LEncounterId"] as EntityField).Clone() as EntityField;
            firstselect.Add(entityField == encounterId);

            entityField = (entity.Fields["LListHeaderId"] as EntityField).Clone() as EntityField;
            firstselect.Add(entityField == hdrId);

            entityField = (entity.Fields["LParentId"] as EntityField).Clone() as EntityField;
            firstselect.Add(entityField == parentId);

            entityField = (entity.Fields["BDeletedFl"] as EntityField).Clone() as EntityField;
            firstselect.Add(entityField == false);

            entityField = (entity.Fields["LAddendumId"] as EntityField).Clone() as EntityField;
            //watch out for addendums
            firstselect.AddWithAnd(entityField == 0);

            tableAorBItems.GetMulti(firstselect, -1, null, relations);

            foreach (IEntity ent in tableAorBItems)
            {
                //This wont work.. just put it here to get the idea. Either use reflection for            LstItems or
                //wrap with interface to partial class for both entities.
                if (ent.Fields["SDescriptionTx"].CurrentValue == ent.LstItems.SDescriptionTx)
                {
                    return ent.Fields["DtLastUpdateDt"].CurrentValue;
                }           
            }
        }


I did not test this code or anything and I am not sure if you can use PropertyInfo.GetValue(null, null) for static types, but it should be doable somehow if that does not work.

And as mentioned in the comment part, you could put the relations behind your own interface, so you could acccess them without reflection.

amccool avatar
amccool
User
Posts: 18
Joined: 08-Jun-2007
# Posted on: 11-Jun-2007 17:18:46   

Hi Sami,

I ended up doing close to the same thing friday (didnt get a chance to post) with reflection. I didnt have the relationship piece done. Looks like you did the hard work for me there. Good to see I wasn't heading down a completely unworkable road.

Thanks! smile Alex