如何将项添加到ISet <t>?</t>

时间:2012-01-16 17:12:07

标签: c# collections

我有三个名为BrokerInstrumentBrokerInstrument的课程。

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; }
}

如果我使用这些类创建三个新对象(每种类型之一)如何关联它们?例如:

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 
};

instrument“如何”知道新的brokerInstrument现在与之相关联?如果我现在运行if (instrument.Brokerinstruments == null),我会true。我是否必须在BrokerInstrument声明中关联对象,然后返回并将其添加到instrument.BrokerInstruments ISet

如果我尝试做:instrument.BrokerInstruments.Add(instrument)我收到错误,因为它为null。困惑。我错过了什么?建模这样的关系的最佳方法是什么?这些对象将使用NHibernate持久保存到数据库中。

3 个答案:

答案 0 :(得分:6)

您得到一个异常,因为您没有初始化Instrument类的BrokerInstruments属性(意味着该属性的值为null)。要解决这个问题,您需要在Instrument上使用构造函数:

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

现在,如果您想要添加乐器的通知,那就是另一个问题。最简单和最安全的方法是使BrokerInstruments属性getter返回IEnumerable,删除setter,并添加AddBrokerInstrument方法:

// 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
}

我使用上面的IEnumerable是因为你想向这个函数的用户表明他们不允许直接将乐器添加到集合中 - 他们需要调用你的方法。

答案 1 :(得分:1)

为了能够添加到集合,您必须首先创建它的实例。这可以在各自的构造函数中完成。我的示例使用HashSet<t>作为ISet<T>的具体实现:

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

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

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 Instrument() {
        BrokerInstruments = new HashSet<BrokerInstrument>(); 
    }     
}

然后,您必须将brokerInstrument对象添加到BrokerInstruments - InstrumentBroker的集合中:

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

答案 2 :(得分:1)

您从未初始化instrument.BrokerInstruments。 您需要:instrument.BrokerInstruments = new ...; 我想新的HashSet或新的SortedSet