2012-01-16 6 views
5

Broker,InstrumentBrokerInstrumentという3つのクラスがあります。ISetにアイテムを追加するには<T>?

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

これらのクラスを使用して3つの新しいオブジェクト(各タイプの1つ)を作成すると、それらをどのように関連付けるのですか?たとえば:

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なのでエラーになります。混乱している。私は何が欠けていますか?このような関係をモデル化する最良の方法は何ですか?これらのオブジェクトは、Hibernateを使用してデータベースに永続化されます。

答えて

5

を推測する(そのプロパティの値を意味するnullです)。それを修正するには、インストゥルメントのコンストラクタを必要とする:あなたが追加されているインストゥルメントの通知をしたい場合は

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

は今、それは別の問題です。最も簡単で安全な方法はBrokerInstrumentsプロパティのゲッターはIEnumerableをを返し、セッターを削除し、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を使用します彼らは直接セットに楽器を追加することはできません - 代わりにあなたのメソッドを呼び出す必要があります。

+0

しかし、ユニットテストを実行すると有望に見えるNHibernateは 'TestFixture failed:NHibernate.PropertyNotFoundException:クラス 'MooDB.Domain.Instrument''内のプロパティ' BrokerInstruments 'のセッターを見つけることができませんでした。NHibernateで特別な処理をする必要がありますか?今?それはかなり複雑に思えますが、私がしたいのは、ドメインモデルで1対多の関係をモデル化して、NHibernateにdbへの変更を永続させることだけです。 –

+0

ああ、私はNHibernateビットを見逃しました。私はそれに応じて修正します...完了。 –

+0

ほぼ! 'protected set'行にエラーが発生しました:'暗黙的に 'System.Collections.Generic.IEnumerable '型を 'System.Collections'に変換できません。Generic.ISet 'を選択します。明示的な変換があります(キャストがありませんか?) –

1

コレクションに追加できるようにするには、実際にそのインスタンスを最初に作成する必要があります。これはそれぞれのコンストラクタで行うことができます。私の例ISet<T>の具体的な実装としてHashSet<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>(); 
    }  
} 

を次にあなたがInstrumentBrokerBrokerInstruments -sets両方にbrokerInstrumentオブジェクトを追加する必要があります。

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); 
+0

名前空間の衝突やキャストエラーのため、このようにしなければなりませんでした: 'BrokerInstruments =(ISet )new System.Collections.Generic.HashSet ();' –

+0

素晴らしい!参考になった場合は回答を受け入れてください。 –

0

あなたはinstrument.BrokerInstrumentsを初期化することはありません。 あなたが必要:instrument.BrokerInstruments = new ...; は、私はあなたがインストゥルメントクラスのBrokerInstrumentsプロパティを初期化されていないため、例外を取得新しいHashSetのか、新しいにSortedSet

関連する問題