开发者

Handling a one-to-many relationship with value types in Fluent NHibernate

I'm working on migrating an application to NHibernate, and I'm using Fluent NHibernate. I'm running into an issue mapping a collection of value types to an aggregate root.

I have a PhoneNumber value type that has a few properties — Number, NumberType, and Description. There are a number of objects in my domain that have collections of phone numbers.

In the database (SQL 2008), these values are held in different tables. So I might have Customers and CustomerPhoneNumbers as well as Vendors and VendorPhoneNumbers. The phone number tables are identical except for the foreign key that relates them to their parent.

开发者_JAVA百科

The problem is that I would like to use a simple PhoneNumber value type without having to create CustomerPhoneNumber and VendorPhoneNumber types that have properties that relate them to their parent type, and I don't know how to accomplish that in NHibernate. Is this possible or do I need to change my domain objects to more closely match the underlying database schema?

UPDATE: A little more info

It looks like I'm having trouble even getting the basic map to work for retrieval. Here's a simplified example of what I have:

public class CustomerMap : ClassMap<Customer>
{
    public CustomerMap()
    {
        Table("Customers");

        Id(x => x.Id);
        Map(x => x.Name);
        Component(x => x.Address);
        HasMany(x => x.PhoneNumbers)
            .KeyColumn("CustomerId")
            .Cascade.All()
            .Table("CustomerPhoneNumbers");
    }
}

public class PhoneNumberMap : ClassMap<PhoneNumber>
{
    public PhoneNumberMap()
    {
        Id(x => x.Id);
        Map(x => x.Number, "PhoneNumber");
        Map(x => x.PhoneNumberType);
        Map(x => x.Description);
    }
}

It looks like the SQL isn't being generated properly. When I try to look into a customer's PhoneNumbers list, I get an ADO error that reveals that NHibernate is looking for a table named PhoneNumber.

It seems like it's not picking up the Table("CustomerPhoneNumbers") part and is defaulting to a table named the same thing as the object. Yet I can't specify a Table in the PhoneNumberMap, because it'll be different depending on which aggregate root we're pulling for.


You can map the single object PhoneNumber to multiple tables using the entity-name mapping attribute. Sorry, no sample code - I do not use Fluent so I cannot help with that aspect. I could post sample hbm mappings if that would be helpful.

Entity-name basically replaces class name across the board. When you use entity-name you will also have to modify your session to accept a parameter to specify the entity name whenever you work with the objects via the session.

Documentation is here:

http://docs.jboss.org/hibernate/core/3.2/reference/en/html/mapping.html#mapping-entityname

EDIT Added hbm samples.

This maps a single object PhoneNumber to multiple tables

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="DomainModel.PhoneNumber, DomainModel"
    table="PhoneNumberVendors" entity-name="PhoneNumberVendor">
    <id name="_id" access="field" column="PhoneNumberId">
        <generator class="assigned"/>
    </id>
    <property name= "...">
    </class>
<class name="DomainModel.PhoneNumber, DomainModel"
    table="PhoneNumberCustomers" entity-name="PhoneNumberCustomer">
    <id name="_id" access="field" column="PhoneNumberId">
        <generator class="assigned"/>
    </id>
    <property name= "...">
    </class>
</hibernate-mapping>

Then to call for example an update on a PhoneNumber you modify the session syntax to the following so nhibernate knows which table to use:

_session.Update("PhoneNumberCustomer", myCustomerNumber) 

You will have to figure out if Fluent even supports this, if so how to do it. If not you can always use hbm files for the PhoneNumber object.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜