views:

260

answers:

3

Hi

I need to map a class which has a list of Enums to a db table, using NHibernate

here are the objects

public class Driver : IIdentity
{
    private IList<Licence> licences;

    /// <summary>
    /// The drivers licences
    /// </summary>
    public virtual IList<Licence> Licences
    {
        get
        {
            return this.licences;
        }
        set
        {
            this.licences = value;
        }
    }
    ..... rest of the class ....
}

//the enum
public enum Licence
{
    FivePersonCar = 5,
    SixPersonCar = 6
}

---------------- here is the DB table

TABLE [dbo].[DriverLicence]( [DriverId] [int] NOT NULL, [Level] [int] NOT NULL)

TABLE [dbo].[Driver]( [DriverId] [int] NOT NULL, [Name] [varchar](150) NULL)

-------------Here is my Fluent map for Driver

public class DriverMap : ClassMap<Driver>
{
    public DriverMap()
    {
        Id(x => x.Id).WithUnsavedValue(0).GeneratedBy.Identity();

        Map(x => x.Name);

        HasManyToMany(x => x.Licences)
            .WithTableName("DriverLicence")
            .AsElement("Level").AsBag();


        HasManyToMany(x => x.InsuredToDrive)
            .CollectionType<InsurancedList>()
            .WithTableName("InsuredWith");
    }

}

----- This generates the following HBM file

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="">
  <class name="Taxi.DomainObjects.Driver, Taxi.DomainObjects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Driver`" xmlns="urn:nhibernate-mapping-2.2">
    <id name="Id" type="Int32" unsaved-value="0" column="DriverID">
      <generator class="identity" />
    </id>
    <property name="Name" type="String">
      <column name="Name" />
    </property>
    <bag name="Licences" table="DriverLicence">
      <key column="DriverId" />
      <many-to-many column="LicenceId" class="Taxi.DomainObjects.Licence, Taxi.DomainObjects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </bag>
    <bag name="InsuredToDrive" collection-type="Taxi.DomainObjects.Collections.InsurancedList, Taxi.DomainObjects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="InsuredWith">
      <key column="DriverId" />
      <many-to-many column="CarId" class="Taxi.DomainObjects.Car, Taxi.DomainObjects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </bag>
  </class>
</hibernate-mapping>


here is my error

"An association from the table DriverLicence refers to an unmapped class: Taxi.DomainObjects.Licence"

anyone know what im doing wrong?

A: 

This is exactly what I asked here. Through my own toying around, I could not figure out how to make it work, so I ended up having to do a sort of workaround.

to translate what I did into your code:

Change your License classname to something else (in this case I will use LicenseCode), and then create an object called License. This object, in my case at least, has an Id and a name. The id is actually the integer value assigned in my Enum. You could use the name of the enum in the same way if you wanted, and just chage the code below to translate on name instead of the id. In the class, add a property like this:

public virtual LicenseCode LicenseCode 
{
     get
     {
         return (LicenseCode)LicenseId;
     }
}

Then, create a table to match the data you will be storing for this object (id and name)

Then, create the mapping. This will be straight-forward as you are only mapping the Id and the name.

Josh
Thanks for your answer, i replied on your post, and left a good link
dbones
+2  A: 

Enums are considered a primitive type by NHibernate, so you should not map using a many-to-many with a class attribute. In .hbm terms, you'd need something like this:

<bag name="Licences" table="DriverLicence">
  <key column="DriverId" />
  <element column="LicenceId" type="Taxi.DomainObjects.Licence, Taxi.DomainObjects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</bag>

Although in hbm mapping like this you can omit the long type attribute. My Fluent syntax is not very good, so I can't help you there I'm afraid. This question may help further.

John Rayner
HasMany(x => x.Licences) .WithTableName("DriverLicence") .AsElement("Level").AsBag();
dbones
A: 

Have you considered using the Flags attribute with your enum class instead of having a list of them?

Martin R-L
Hi im not sure what you mean, I wanted a list of Licences (Enums) for a driver (this is a demo app). how would the flag arrtibute on the enum (Licence) be an alternative? if this is better than the implemented senario im using, feel free to inform me. else the main issue has been solved
dbones