2010-02-18 30 views
5

Tôi đang sử dụng hai lớp NiceCustomer & RoughCustomer có nghĩa là giao diện ICustomer.Làm thế nào để ánh xạ một giao diện trong nhibernate?

ICustomer có bốn thuộc tính. Đó là:

  1. Property Id() As Integer
  2. Property Name() As String
  3. Property IsNiceCustomer() As Boolean
  4. ReadOnly Property AddressFullText() As String

Tôi không biết làm thế nào để lập bản đồ giao diện ICustomer, cơ sở dữ liệu.

Tôi gặp lỗi như thế này trong ngoại lệ bên trong.

hiệp hội Một đề cập đến một lớp unmapped: ICustomer

Tôi đang sử dụng Fluent và NHibernate.

+0

Tôi không nghĩ rằng bạn cần ánh xạ bất kỳ giao diện nào như vậy .. bạn có thể vui lòng đăng các tệp ánh xạ của mình không? Cảm ơn –

+0

Cảm ơn bạn đã trả lời Mahesh. Nhưng như Kevin đã nói chúng tôi không thể ánh xạ một giao diện trong nhibernate. Tôi đã thay đổi giao diện thành một lớp cơ sở. – Josh

Trả lời

0

Không thể ánh xạ giao diện trong chế độ nhibernate. Nếu mục tiêu của bạn là có thể truy vấn bằng cách sử dụng loại phổ biến để truy xuất cả hai loại khách hàng, bạn có thể sử dụng truy vấn đa hình. Đơn giản chỉ cần có cả hai lớp của bạn thực hiện giao diện và ánh xạ các lớp bình thường. Xem tham chiếu này:

https://www.hibernate.org/hib_docs/nhibernate/html/queryhql.html (phần 11.6)

+0

Tôi cũng đã thử truy vấn đa hình nhưng nó không hoạt động. Vẫn gặp sự cố với khách hàng giao diện chưa được ánh xạ đó. Vì vậy, làm cho nó một lớp cơ sở bây giờ mà hoạt động tốt. Cảm ơn Kevin nhiều. – Josh

+0

"Nó là hoàn toàn có thể chấp nhận cho lớp kiên trì được đặt tên là một giao diện. Sau đó bạn sẽ khai báo thực hiện các lớp của giao diện đó bằng cách sử dụng phần tử ." từ http://knol.google.com/k/fabio-maulo/nhibernate-chapter-5-basic-o-r-mapping/1nr4enxv3dpeq/8# – Neal

+3

Liên kết trong câu trả lời này bị hỏng. Vui lòng cập nhật liên kết hoặc thêm chi tiết khác vào câu trả lời của bạn. –

0

bạn đang truy vấn như thế nào? Nếu bạn đang sử dụng HQL bạn cần phải nhập không gian tên của giao diện với một tập tin HBM với dòng này:

<import class="name.space.ICustomer, Customers" /> 

Nếu bạn đang sử dụng Tiêu chuẩn bạn chỉ có thể truy vấn cho ICustomer và nó sẽ trả lại cả hai khách hàng loại.

Nếu bạn đang lập bản đồ một lớp học có một khách hàng vào nó hoặc thông qua một HasMany, HasManyToMany hoặc tài liệu tham khảo thì bạn cần phải sử dụng mẫu chung:

References<NiceCustomer>(f=>f.Customer) 

Nếu bạn muốn nó để đối phó với một trong hai, bạn sẽ cần phải làm cho họ lớp con

Subclassmap<NiceCustomer> 

trong trường hợp này, tôi nghĩ rằng bạn sẽ cần các lớp cơ sở khách hàng và sử dụng cho tham số kiểu chung chung trong các lớp bên ngoài:

References<Customer>(f=>f.Customer) 

Bất kể, bạn không nên thay đổi mô hình miền của mình để đối phó với điều này, nó vẫn phải có một ICustomer ở ​​lớp bên ngoài.

Tôi không chắc liệu 1.0RTM có biểu mẫu Chung làm việc cho Tài liệu tham khảo hay không nhưng việc quét nhanh các thay đổi sẽ hiển thị thay đổi, mà tôi nghĩ là bổ sung hai dòng.

3

Bạn có thể ánh xạ trực tiếp vào giao diện trong NHibernate, bằng cách cắm vào EmptyInterceptor trong giai đoạn cấu hình.Công việc của kẻ đánh chặn này là cung cấp các triển khai cho các giao diện mà bạn đang định nghĩa trong các tệp ánh xạ của mình.

public class ProxyInterceptor : EmptyInterceptor 
{ 
    public ProxyInterceptor(ITypeHandler typeHandler) { 
     // TypeHandler is a custom class that defines all Interface/Poco relationships 
     // Should be written to match your system 
    } 

    // Swaps Interfaces for Implementations 
    public override object Instantiate(string clazz, EntityMode entityMode, object id) 
    { 
     var handler = TypeHandler.GetByInterface(clazz); 
     if (handler == null || !handler.Interface.IsInterface) return base.Instantiate(clazz, entityMode, id); 
     var poco = handler.Poco; 
     if (poco == null) return base.Instantiate(clazz, entityMode, id); 

     // Return Poco for Interface 
     var instance = FormatterServices.GetUninitializedObject(poco); 
     SessionFactory.GetClassMetadata(clazz).SetIdentifier(instance, id, entityMode); 

     return instance; 
    } 

} 

Sau này, tất cả các mối quan hệ và ánh xạ có thể được định nghĩa là giao diện.

public Parent : IParent { 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public IChild Child { get; set; } 
} 

public Child : IChild { 
    public int ID { get; set; } 
    public string Name { get; set; } 
} 

public class ParentMap : ClassMap<IParent> 
{ 
    public ParentMap() 
    { 
     Id(x => x.ID).GeneratedBy.Identity().UnsavedValue(0); 
     Map(x => x.Name) 
    } 
} 

... 

Loại kỹ thuật này là tuyệt vời nếu bạn muốn thực hiện tách ORM, đặt tất cả cấu hình/ánh xạ trong một dự án riêng biệt và chỉ tham chiếu giao diện. Lớp miền của bạn sau đó không bị ô nhiễm với ORM và sau đó bạn có thể thay thế nó ở giai đoạn sau nếu cần.

+0

Bạn có thể thêm một ví dụ về việc sử dụng ProxyInterceptor trong cấu hình không? Tôi chỉ mới bắt đầu sử dụng Fluent Nhibernate ngay bây giờ và không đủ quen thuộc với phần cấu hình để biết nơi để chỉ định proxy ... –

+0

Tôi đã có thể làm cho nó hoạt động, nhưng vấn đề là lớp Domain vẫn bị ô nhiễm quá mức Phương pháp cụ thể ORM - chủ yếu là các bộ định vị trên các thuộc tính. ORM cần để có thể đặt giá trị trên mỗi trường, trong khi trong đối tượng Miền tôi KHÔNG muốn làm cho nó có thể thay đổi trường Id của một đối tượng (cùng với nhiều thuộc tính chỉ đọc khác). –

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