BusinessBase/BusinessListBase Problem (Maybe???)

BusinessBase/BusinessListBase Problem (Maybe???)

Old forum URL: forums.lhotka.net/forums/t/3778.aspx


Phlar posted on Thursday, October 25, 2007

I am having a strange issue when adding an object to the collection in which it replaces the details of any existing object already in the collection that has the same name.  For example:

public class A : BusinessBase<A>

{

    private string _name = string.empty;

    private XmlDocument _xmlDocumentDetails;

    private int _versionNumber = 0;

    ... Getter/Setter routines here....

}

public class AList: BusinessListBase<AList, A>

{

    public A GetItem(string name, int version)

    {

         foreach (A aItem in this)

        {

                if ((aItem.Name.Equals(name)) && (aItem.VersionNumber == version))

               {

                   return aItem;

               }

        }

        return null;

    }

    public void AddA(A aItem)

    {

        if (!Contains(aItem.Name, aItem.VersionNumber))

        {

             this.Add(aItem);

        }

        .... etc....

    }

}

Now if I have one XML as follows:

<Names>

    <Name>

        <First>Joe</First>

        <Last>Smith</Last>

    </Name>

</Names>

and another one as follows:

<Names>

    <Name>

        <First>John</First>

        <Last>Smith</Last>

    </Name>

    <Name>

        <First>Jane</First>

        <Last>Smith</Last>

    </Name>

</Names>

 

I can add the items into the collection as follows:

AList aItemList = AList.NewAList();

A aItem = A.NewA();

aItem.Name = "Test1";

aItem.DocumentDetails = XML1;

aItem.VersionNumber = 1;

aItemList.AddA(aItem);

 

A aItem2 = A.NewA();

aItem2.Name = "Test1a";

aItem2.DocumentDetails = XML2;

aItem2.VersionNumber = 1;

aItemList.AddA(aItem);

 

This apparently works but if execute the following:

AList aItemList = AList.NewAList();

A aItem = A.NewA();

aItem.Name = "Test1";

aItem.DocumentDetails = XML1;

aItem.VersionNumber = 1;

aItemList.AddA(aItem);

 

A aItem2 = A.NewA();

aItem2.Name = "Test1";

aItem2.DocumentDetails = XML2;

aItem2.VersionNumber = 2;

aItemList.AddA(aItem);

 

The xml details for both objects in the collection will be the same.  Any ideas?

 

KKoteles replied on Thursday, October 25, 2007

Phlar,

It may be a typo, but if I read you code correctly then here is your problem.  You are always calling aItemList.AddA(aItem) and never calling aItemList.AddA(aItem2).  I'm surprised it works the first time.  You never add the second item - you are always trying to add the first item twice.

If what you listed is actually a typo, then could you list the Contains method of the list?  I could see where that might stop the second one from being added; however, it doesn't account for why it would be adding a completely different object.

It also seems a little strange that you would be adding to the list externally.  Most of my lists had a method that was called and the list object itself did what it needed to to load the child objects.  If it is a ReadOnlyListBase object then you need to worry about things like setting RaiseListChangedEvents and IsReadOnly as you load it.  From the code displayed here, you are not addressing those issues.

Ken

Phlar replied on Thursday, October 25, 2007

KKoteles,

You are correct that was a typo.  The sample problem's second add to the aItemList collection should have been:

aItemList.AddA(aItem2) as you've mentioned.

Here is the Contains method:

public bool Contains(string name, int version)

{

    foreach(A aItem in this)

    {

        if ((aItem.Name.Equals(name)) && (aItem.VersionNumber == version)

            return true;

        return false;

    }

}

As an aside note, it actually does add both items to the collection, however the document details are identical (i.e. the XML are identical) when they shouldn't be.  That is what has me completely perplexed.  I can utilzie the GetItem(Name, Version) to obtain both items and when I examine the XML details, they are the same.  The XML details are actually changed during run time.  The original one is retrieved from file (XML Example1) and subsequently modified to resemble (XML Example 2) if that helps any.

I should also mention that the above code are in two different classes.  I omitted the extra details in order to simplify the details in the post, conserve space and company knowledge.

Thanks for any additional comments/suggestions.

 

RockfordLhotka replied on Thursday, October 25, 2007

You are properly implementing GetIdValue() in the child objects, so each object returns a unique ID right? This is a common oversight, but since .NET collections use the Equals() method to know which item is which within a list you'll run into trouble if all items in the list don't return unique ID values.

Phlar replied on Thursday, October 25, 2007

Rockford,

That is correct.  The GetIDValue() is implemented in the child object and returns a unique ID value. 

After much searching and additional logging (utilizing Log4Net), I was able to trace it to another class which did not implement the ICloneable interface which resulted in both items referencing the identical XML details. 

 

Copyright (c) Marimer LLC