2012-01-16 31 views
5

Tôi có ba lớp được gọi là Broker, InstrumentBrokerInstrument.Cách thêm một mục vào 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; } 
} 

Nếu tôi tạo ba đối tượng mới (một trong mỗi loại) bằng cách sử dụng các lớp đó làm cách nào để liên kết chúng? Ví dụ:

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

như thế nào instrument "biết" rằng một mới brokerInstrument hiện đang liên kết với nó? Nếu bây giờ tôi chạy if (instrument.Brokerinstruments == null) tôi nhận được true. Tôi có phải liên kết các đối tượng trong cả tuyên bố BrokerInstrument và sau đó quay lại và thêm nó vào instrument.BrokerInstruments ISet?

Nếu tôi cố gắng thực hiện: instrument.BrokerInstruments.Add(instrument) Tôi gặp lỗi vì giá trị rỗng của nó. Bối rối. Tôi đang thiếu gì? Cách tốt nhất để mô hình các mối quan hệ như thế này là gì? các đối tượng này sẽ tiếp tục tồn tại trong cơ sở dữ liệu bằng NHibernate.

Trả lời

5

Bạn nhận được một ngoại lệ bởi vì bạn không khởi tạo BrokerInstruments tài sản của lớp Instrument (có nghĩa là giá trị của tài sản đó là null). Để khắc phục điều đó, bạn cần một hàm tạo trên Công cụ:

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

Bây giờ nếu bạn muốn thông báo về Công cụ được thêm vào, đó là một vấn đề khác. Cách dễ nhất và an toàn nhất là làm cho BrokerInstruments tài sản getter trả lại một IEnumerable, loại bỏ các setter, và thêm một phương pháp 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 
} 

tôi sử dụng một IEnumerable trên bởi vì bạn muốn chỉ ra cho người sử dụng chức năng này họ không được phép thêm trực tiếp các công cụ vào nhóm - họ cần phải gọi phương thức của bạn thay thế.

+0

Trông đầy hứa hẹn tuy nhiên khi tôi chạy một thử nghiệm đơn vị NHibernate than phiền với 'TestFixture thất bại: NHibernate.PropertyNotFoundException: Không thể tìm thấy một setter cho tài sản 'BrokerInstruments' trong lớp 'MooDB.Domain.Instrument'' Tôi có cần phải làm một cái gì đó đặc biệt trong NHibernate hiện nay? Nó có vẻ khá phức tạp, nhưng tất cả tôi muốn làm là mô hình một mối quan hệ một-nhiều trong một mô hình miền và sau đó có NHibernate tồn tại những thay đổi liên tục cho db. –

+0

Ah, tôi đã bỏ lỡ bit NHibernate. Tôi sẽ sửa đổi cho phù hợp ... Xong. –

+0

Hầu như! trên dòng 'protected set' tôi nhận được lỗi:' Không thể chuyển đổi hoàn toàn kiểu 'System.Collections.Generic.IEnumerable ' thành 'System.Collections.Generic.ISet '. Một chuyển đổi rõ ràng tồn tại (bạn đang bỏ lỡ một diễn viên?) ' –

1

Để có thể thêm vào bộ sưu tập, trước tiên bạn phải tạo một phiên bản của nó. Điều này có thể được thực hiện trong các nhà thầu tương ứng. ví dụ của tôi sử dụng HashSet<t> như việc thực hiện cụ thể của 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>(); 
    }  
} 

Sau đó, bạn phải thêm đối tượng brokerInstrument cho cả BrokerInstruments -sets của 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); 
+0

Cảm ơn, tôi phải làm như vậy vì các xung đột không gian tên và lỗi truyền: 'BrokerInstruments = (ISet ) new System.Collections.Generic.HashSet ();' –

+0

Tuyệt vời! Vui lòng chấp nhận câu trả lời nếu nó hữu ích. –

0

Bạn instrument.BrokerInstruments không bao giờ được khởi tạo. Bạn cần: instrument.BrokerInstruments = new ...; Tôi đoán HashSet mới hoặc mới SortedSet

Các vấn đề liên quan