Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add an item to an ISet<T>?

Tags:

c#

collections

I have three classes called Broker, Instrument and BrokerInstrument.

using Iesi.Collections.Generic;

public class Broker : ActiveDefaultEntity
{
    public virtual string Name { get; set; }
    public virtual ISet<BrokerInstrument> BrokerInstruments { get; set; }
}

public class Instrument : Entity
{
    public virtual string Name { get;  set; }
    public virtual string Symbol {get;  set;}
    public virtual ISet<BrokerInstrument> BrokerInstruments { get; set; }
    public virtual bool IsActive { get; set; }        
}

public class BrokerInstrument : Entity
{
    public virtual Broker Broker { get; set; }
    public virtual Instrument Instrument { get; set; }
    public virtual decimal MinIncrement { get; set; }
}

If I create three new objects (one of each type) using those classes how to I associate them? For example:

Instrument instrument = new Instrument { 
    Name = "Test Instrument", 
    Symbol = "Test", 
    IsActive = true 
};
Broker broker = new Broker { 
    Name = "My Test Broker", 
    IsActive = true, 
    IsDefault = false 
};
BrokerInstrument brokerInstrument = new BrokerInstrument { 
    Broker = broker, 
    Instrument = instrument, 
    MinIncrement = 0.01M 
};

How does the instrument "know" that a new brokerInstrument is now associated with it? If I now run if (instrument.Brokerinstruments == null) I get true. Do I have to associate the objects in both the BrokerInstrument declaration and then go back and add it to the instrument.BrokerInstruments ISet?

If I try and do: instrument.BrokerInstruments.Add(instrument) I get an error because its null. Confused. What am I missing? What is the best way to model relationships like this? these objects will get persisted to a database using NHibernate.

like image 631
Mark Allison Avatar asked Jan 16 '12 17:01

Mark Allison


2 Answers

You get an exception because you are not initializing the BrokerInstruments property of the Instrument class (meaning the value of that property is null). To fix that, you need a constructor on Instrument:

public Instrument() {
    BrokerInstruments = new HashSet<BrokerInstrument>();
}

Now if you want notification of an Instrument being added, that's a different problem. The easiest and safest way is to make the BrokerInstruments property getter return an IEnumerable, remove the setter, and add a AddBrokerInstrument method:

// With this, you don't need the constructor above.
private ISet<BrokerInstrument> _brokerInstruments = new HashSet<BrokerInstrument>();

public virtual IEnumerable<BrokerInstrument> BrokerInstruments { 
    get { return _brokerInstruments; } 

    // This setter should allow NHibernate to set the property while still hiding it from external callers
    protected set { _brokerInstruments = new HashSet<BrokerInstrument>(value); } 
}

public void AddBrokerInstrument(BrokerInstrument brokerInstrument) { 
     // Any other logic that needs to happen before an instrument is added
     _brokerInstruments.Add(brokerInstrument); 
     // Any other logic that needs to happen after an instrument is added
}

I use an IEnumerable above because you want to indicate to the users of this function that they are not allowed to add instruments directly to the set- they need to call your method instead.

like image 161
Chris Shain Avatar answered Sep 21 '22 06:09

Chris Shain


You never initialized instrument.BrokerInstruments. You need: instrument.BrokerInstruments = new ...; I guess new HashSet or new SortedSet

like image 38
watbywbarif Avatar answered Sep 21 '22 06:09

watbywbarif