2009-04-01 25 views
9

Tôi chắc chắn đây là một câu hỏi đơn giản nhưng hãy cân nhắc những điều sau đây: Tôi có một tham chiếu giữa công ty và ngành như sau:thành thạo NHibernate - Làm thế nào để lập bản đồ cột chính nước ngoài như một tài sản

public class Company { 
    public Guid ID { get; set; } 
    public Sector Sector { get; set; } 
    public Guid SectorID { get; set; } 
} 

public class Sector { 
    public Guid ID { get; set; } 
    public string Name { get; set; } 
} 

Ok. Điều tôi muốn là SectorID của đối tượng Công ty được điền sau khi tôi đi:

(new Company()).Sector = new Sector() { Name="asdf" } 

và thực hiện xả.

Ánh xạ tôi đang sử dụng vui lòng tạo cột bổ sung trong cơ sở dữ liệu được gọi là Sector_Id trong bảng Công ty, nhưng điều này không có sẵn dưới dạng thuộc tính trên Công ty. Tôi muốn điền thuộc tính SectorID.

Việc lập bản đồ Tôi hiện đang sử dụng trong CompanyMap là

References(c => c.Sector).Cascade.All(); 

Có ai có bất kỳ ý tưởng?


Cảm ơn bạn đã trả lời. Đáng buồn là nếu tôi làm tùy chọn thứ hai (đặt tên cột của cột để được giống như tài sản, hoặc thiết lập Map(x => x.SectorID, "Sector_Id") sau đó tôi nhận được lỗi:

System.IndexOutOfRangeException: chỉ số không hợp lệ 7 cho SqlParameterCollection này với Count = 7.

Tôi có thể phải thực hiện tùy chọn đầu tiên nhưng tôi lo ngại rằng một truy vấn bổ sung sẽ được kích hoạt khi bạn gọi SectorID nhận được vì nó tự lấy ngành ra khỏi db (trừ khi nó được tải háo hức một chút rắc rối)

Tôi ngạc nhiên không có câu trả lời dễ dàng cho việc này.


WOW! Nếu tôi sử dụng

public virtual Guid SectorID 
{ 
    get { return Sector.ID; 
} 

sau đó nhibernate là đủ thông minh để biết rằng cột Sector_id trong truy vấn Tổ chức thực sự là điều tương tự như Sector.ID và nó sẽ trả về này dưới mũ trùm. Nó không gửi ra một truy vấn bổ sung ngay cả khi bạn tải chậm. Tôi rất ấn tượng!


Theo dõi ... Có vẻ như ngủ đông không thực sự được viết để có thể ánh xạ cột khóa ngoài trong đối tượng. Mặc dù điều này có thể là một chút đau ở mặt trước web nhưng nó có ý nghĩa vì đây thực sự là một mối quan tâm dai dẳng không thực sự là một mối quan tâm đối tượng. Tôi đang sử dụng asp.net MVC và đã viết một mô hình tùy chỉnh chất kết dính sẽ lấy một hộp đầu vào của tên Liên hệ (chứ không phải là ContactID), mới lên một liên hệ mới với ID của những gì trong texbox, và sau đó áp dụng điều này để tài sản của Mô hình. Điều này xung quanh vấn đề với danh sách thả xuống trong giao diện người dùng web. Sẽ đăng mã nếu có ai quan tâm.

Trả lời

2

Hai suy nghĩ: Trước hết, sẽ không có điều gì như thế này đạt được những gì bạn muốn?

public class Company { 
    public Guid ID { get; set; } 
    public Sector Sector { get; set; } 
    public Guid SectorID { 
     get { return Section.ID; } 
     // Really not sure what behavior your setter should have here; Maybe it shouldn't even have one? 
     set { Sector = new Sector { ID = value }; } 
    } 
} 

Thứ hai, khi bạn nói rằng ánh xạ tạo cột trong DB được gọi là Sector_Id, ngoài cột bạn đã tạo SectorID?Nếu vậy, bạn có thể thay đổi tên cột sao cho nó sử dụng tên chính xác (here's the documentation for mappings, xem một vài tiêu đề "Chỉ định tên cột").

Ngoài ra, bạn có đang lập bản đồ thuộc tính SectorID (ví dụ: "Bản đồ (x => x.SectorID," Sector_Id ")") không?

2

Steve bạn không cần thuộc tính ForeignKey trong lớp POCO.

Ví dụ: nếu bạn sẽ cố gắng lấy id của tác giả bài viết không chọn tham gia sẽ được thực hiện.

var authorID = Article.Author.ID

13

Điều này dễ dàng được thực hiện với thuộc tính công thức.

public class Company { 
    public virtual Guid Id { get; set; } 
    public virtual Guid? SectorId { get; set; } 
    public virtual Sector Sector { get; set; } 
} 

public class CompanyMap : ClassMap<Company> { 
    public CompanyMap() { 
    Id(x => x.Id); // Maps to a column named "Id" 
    References(x => x.Sector); // Maps to a column named "Sector_id", unless you change the NHibernate default mapping rules. 
    Map(x => x.SectorId).Formula("[Sector_id]"); 
    }  
} 

Điều này sẽ hoạt động chính xác theo cách bạn muốn. Khi số Company là mới, SectorId sẽ là rỗng; khi Company được tìm nạp từ DB, SectorId sẽ được điền bằng giá trị công thức đã cho. Các SectorId được tiếp xúc như là một tài sản, mà làm cho nó thực sự tốt đẹp để đối phó với thả xuống web, vv Khi bạn tiết kiệm, bạn vẫn sẽ cần phải ràng buộc các "thực sự" hiệp hội. Giả sử rằng SectorId đã được chọn trong một biểu mẫu ...

using (var txn = session.BeginTransaction()) { 
    // Set the FK reference. 
    company.Sector = session.Load<Sector>(company.SectorId); 
    // Save the new record. 
    session.Save(company); 
    // Commit the transaction. 
    txn.Commit(); 
} 
+0

Tôi cung cấp cho bạn điểm để giải quyết lỗi tôi nhận được, nhưng điều này có vẻ hoàn toàn không trực quan. Nó có vẻ giống như một vấn đề thiết kế trong NHibernate nếu nó không thể xử lý một kịch bản phổ biến như có cả ID FK và đối tượng liên kết-dụ như các thuộc tính. –

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