2010-03-07 13 views
8

Hãy xem xét tôi có một lớp cha mẹ, lớp mối quan hệ con và lập bản đồ. Tôi đang sử dụng NHibernate để đọc các đối tượng từ cơ sở dữ liệu, và dự định sử dụng WCF để gửi các đối tượng trên dây.Dừng tải chậm hoặc bỏ qua tải thuộc tính trong NHibernate? Proxy không thể được tuần tự hóa thông qua WCF

Goal

  • Để đọc các đối tượng phụ huynh, tôi muốn chọn lọc, tại con đường thực hiện khác nhau, quyết định khi nào tôi muốn tải các đối tượng trẻ em. Bởi vì tôi không muốn đọc nhiều hơn những gì tôi cần.
  • Đối tượng tải một phần này phải được gửi qua WCF. Khi tôi có nghĩa là tôi không tải nó, không bên nào sẽ truy cập tài sản đó.

Vấn đề

  • Khi đối tượng được nạp một phần như vậy đang được gửi qua WCF, như những tài sản được đánh dấu là [DataContract], nó có thể không được tuần tự như tài sản là Proxy tải lười biếng thay vì loại thực nổi tiếng.

Những gì tôi muốn lưu trữ, hoặc giải pháp mà tôi có thể nghĩ đến

  • lazy=false hoặc lazy=true không hoạt động. Cựu sẽ háo hức lấy tất cả các mối quan hệ, sau này sẽ tạo ra một proxy. Nhưng tôi không muốn gì thay thế - một null sẽ là tốt nhất.
  • Tôi không cần tải chậm. Tôi hy vọng sẽ nhận được một null cho những tài liệu tham khảo mà tôi không muốn tìm nạp. Một null, nhưng không chỉ là một proxy. Điều này sẽ làm cho WCF hạnh phúc, và lãng phí ít thời gian hơn để có một proxy tải lười được xây dựng.
    Giống như tôi có thể có một nhà máy sản xuất proxy không?
    -OR-
  • Hoặc làm cho WCF bỏ qua những thuộc tính đó là proxy thay vì thực. Tôi đã thử the IDataContractSurrogate solution, nhưng chỉ có cha/mẹ được chuyển đến GetObjectToSerialize, tôi không bao giờ quan sát một proxy được chuyển qua số GetObjectToSerialize, không có cơ hội để bỏ proxy đó.

Sửa

Sau khi đọc các ý kiến, lướt hơn trên Internet ...

Dường như với tôi rằng DTO sẽ chuyển phần quan trọng trong việc tính toán để phía máy chủ. Nhưng đối với dự án tôi đang làm việc, 50% thời gian khách hàng "thông minh hơn" so với máy chủ và máy chủ giống như một kho dữ liệu có xác thực và xác minh. Mặc dù tôi đồng ý máy chủ không phải là chính xác câm - Tôi phải quyết định khi nào để lấy các tài liệu tham khảo thêm đã có, và DTO sẽ làm cho điều này rất rõ ràng.

Có lẽ tôi chỉ nên chịu đau. Tôi không biết http://automapper.codeplex.com/ trước đây, điều này thúc đẩy tôi nhiều hơn một chút để có được nỗi đau.

Mặt khác, tôi tìm thấy http://trentacular.com/2009/08/how-to-use-nhibernate-lazy-initializing-proxies-with-web-services-or-wcf/, có vẻ như đang hoạt động với IDataContractSurrogate.GetObjectToSerialize.

+8

không gửi các thực thể qua dây. Sử dụng DTO, khi đó bạn sẽ không bao giờ gặp sự cố với proxy tải xuống –

+0

http://stackoverflow.com/questions/577201/returning-nhibernate-mapping-classes-from-wcf-services http://stackoverflow.com/questions/616314/are-there-any-gotchas-khi-sử dụng-castle-activerecord-nhibernate-with-wcf http://stackoverflow.com/questions/2312563/nhibernate-lazy-initialized-collection-on-wcf-wire http : //stackoverflow.com/questions/1681538/nhibernate-and-wcf-serializationunidirectional –

+0

Không biết về automapper. Có lẽ tôi nên đi với DTO. – HelloSam

Trả lời

1

Tôi đã gặp sự cố tương tự với hiệu suất, thay vào đó, tôi đã tải trước thông tin mình muốn bằng cách sử dụng lệnh gọi rõ ràng tới DB bằng cách sử dụng DetachedCriteria.

Vì vậy, tương tự như những gì bạn đang làm tôi có thể sẽ làm một cái gì đó như thế này.

public DetachedCriteria BuildMyCriteria() 
{ 
    var criteria = DetachedCriteria.For<ParentClass>(); 
    criteria.CreateCriteria("this.ChildClass", "Child Class").SetFetchMode("this.ChildClass", FetchMode.Eager); 
    criteria.Add(Restrictions.IsNotNull("ChildClass.Property");  

    return criteria; 
} 

Sau đó, từ mặt tiền của tôi, tôi sẽ nhận được những thực thể với các thuộc tính mà không có các thuộc tính null trên tài sản

var myClasses = _repository.ExecuteDetachedCriteria<ParentClass>(BuildMyCriteria); 

con Sau đó, tôi sẽ có tất cả các thực ParentClass rằng có một tài sản null.

Vì vậy, thay vì nhấn mạnh bằng cách liên tục hỏi DB để biết thông tin, tôi lưu trữ nó trong bộ nhớ để sẵn sàng cho tôi sử dụng.

Đây chỉ là một giải pháp thay thế cho DTOs, chúc may mắn :)

2

Đã nhận được cùng một vấn đề với WCF Silverlight chuyển của DTO/Entities. Tôi sử dụng đoạn mã sau đó hoạt động tốt:

thành thạo NHibernate:

References(c => c.DataSource) 
    .Column("DataSourceId") 
    .Cascade.None() 
    .Not.LazyLoad(); 
HasManyToMany(c => c.Categories) 
    .Table("Categories") 
    .ParentKeyColumn("ItemId") 
    .ChildKeyColumn("CategoryId") 
    .Not.LazyLoad() 
    .Cascade.None() 
    .Inverse(); 

XML:

<many-to-one name="DataSource" column="DataSourceId" lazy="false" cascade="none" /> 

Hy vọng điều này sẽ làm việc cho bạn!