2009-03-23 14 views
31

Tôi vừa chuyển sang chế độ Fluent NHibernate và tôi đã gặp sự cố và không tìm thấy bất kỳ thông tin nào về nó.Fluent NHibernate, làm việc với giao diện

Dưới đây là các trường hợp:

public class Field : DomainObject, IField 
{ 
    public Field() 
    { 
    } 

    public virtual string Name { get; set; } 
    public virtual string ContactPerson { get; set; } 
    public virtual bool Private { get; set; } 
    public virtual IAddress Address { get; set; } 
} 

IAddress là một giao diện được thực hiện bởi một lớp có tên Địa chỉ

public class Address : DomainObject, IAddress 
{ 
    public Address() 
    { 
    } 

    public virtual string City { get; set; } 
    public virtual string Country { get; set; } 
    public virtual string PostalCode { get; set; } 
    public virtual string StreetAddress { get; set; } 
} 

Dưới đây là file bản đồ của tôi cho cả hai lớp

CHỈ

public class AddressMap : ClassMap<Address> 
{ 
    public AddressMap() 
    { 
     WithTable("Addresses"); 
     Id(x => x.Id, "Id").Access.AsCamelCaseField(Prefix.Underscore).GeneratedBy.Guid(); 
     Map(x => x.City, "City"); 
     Map(x => x.Country, "Country"); 
     Map(x => x.PostalCode, "PostalCode"); 
     Map(x => x.StreetAddress, "StreetAddress"); 
    } 
} 

LĨNH VỰC

public class FieldMap : ClassMap<Field> 
{ 
    public FieldMap() 
    { 
     WithTable("Fields"); 
     Id(x => x.Id, "Id").Access.AsCamelCaseField(Prefix.Underscore).GeneratedBy.Guid(); 
     Map(x => x.Name, "Name"); 
     Map(x => x.ContactPerson, "ContactPerson"); 
     Map(x => x.Private, "Private"); 
     References(x => x.Address, "AddressId").Cascade.Delete().Cascade.SaveUpdate(); 
    } 
} 

Vì vậy, khi tôi cố gắng truy xuất một đối tượng lĩnh vực từ cơ sở dữ liệu của tôi, tôi nhận được một lỗi NHibernate mà nói rằng IAddress không được ánh xạ. Có cách nào để chỉ định NHibernate để sử dụng lớp Địa chỉ trong ánh xạ?

Vui lòng cho tôi biết nếu cần thêm thông tin.

Thanks a lot,

Charles

+0

Bạn định hình mô hình phân cấp IAddress trong cơ sở dữ liệu như thế nào? Bảng mỗi phân cấp (một bảng chứa tất cả các loại địa chỉ), hoặc bảng theo từng lớp cụ thể? Bạn nói rằng bạn đã chuyển sang Fluent để đăng một bản đồ XML mẫu có thể giúp xác định những gì bạn đang cố gắng thực hiện. –

+0

Trong thực tế, tôi chuyển từ ADO.NET Entity Framework sang Nhibernate với Fluent NHibernate. Trong cơ sở dữ liệu của tôi, có một bảng chứa tất cả các loại địa chỉ. Nhân tiện, tôi quyết định loại bỏ các giao diện đó, tôi nhận ra rằng nó vô dụng. Nhưng tôi nghĩ câu hỏi vẫn còn hợp lệ. Cảm ơn, Charles –

Trả lời

35

Tôi thấy rằng có các lý do hợp lệ để sử dụng giao diện thay vì lớp bê tông làm thuộc tính.

Ví dụ: nếu lớp Field của bạn nằm trong một dự án riêng biệt với lớp Địa chỉ và bạn không có sự phụ thuộc vào dự án của lớp Địa chỉ từ dự án của lớp Field.

Có nhiều cách khác để đối phó với tình huống này, nhưng cách đơn giản nhất thường là cố gắng những gì bạn đang làm và giải thích cho NHibernate lớp bê tông để sử dụng cho IAddress.

Bây giờ bạn có thể làm điều này trong thành thạo NHibernate, như thế này:

References(x => x.Address, "AddressId") 
    .Class(typeof(Address); 

Đáng tiếc là bạn không thể làm điều này với HasMany hoặc HasManyToMany. Tôi không chắc chắn nếu điều này thậm chí sẽ có thể do thiếu hỗ trợ hiệp phương sai tốt trong C#.

+26

** Cập nhật: ** Bạn có thể sử dụng 'Tài liệu tham khảo

(x => x.Address) .Column ("AddressID");' Bạn có thể làm tương tự với 'HasMany' và 'HasManyToMany' bằng cách thêm tham số kiểu generic. – Jay

+0

+1 để cập nhật, chỉ là những gì tôi đang tìm kiếm, cảm ơn rất nhiều. – 4imble

+0

Cảm ơn rất nhiều, chính xác những gì tôi đang tìm kiếm cũng ... đã cố gắng làm .CollectionType() xích vào HasMany của tôi(), nhưng điều đó dường như không hoạt động. – calebt

5

Mở đối tượng lĩnh vực của bạn, bạn có một đối tượng kiểu IAddress. Điều này có thể được thực hiện bởi bất kỳ số lần triển khai khác nhau nào. Với những gì bạn đang yêu cầu, mỗi thực hiện sẽ có bản đồ riêng của mình, mà sẽ giới thiệu bất kỳ số khó khăn (impossibilities?) Cho NHibernate để xử lý.

Một ví dụ đơn giản sẽ giúp chứng minh. Giả sử bạn có hai triển khai IAddress Address1 và Address2. Chúng được lưu trong bảng riêng của chúng, tblAddress1 và tblAddress2. Khi bạn cố gắng tải đối tượng Field của bạn, tất cả NHibernate biết là bạn có một cái gì đó mà thực hiện IAddress, nó không biết được thực hiện đã được duy trì. Làm thế nào nó có thể biết được ánh xạ để sử dụng để lấy đối tượng con cho bất kỳ trường nào?

Tôi chắc chắn có nhiều biến chứng hơn, nhưng ví dụ này cho thấy lý do tại sao bạn phải có ánh xạ cho loại đối tượng chính xác mà bạn đã khai báo.

0

Nếu bạn quan tâm đến việc tách ORM hoàn toàn khỏi lớp miền và tham chiếu giao diện trong lớp dữ liệu thay vì chỉ định các lớp cụ thể, bạn có thể triển khai một EmptyInterceptor để ánh xạ giữa hai lớp.

Xem câu trả lời của tôi here.