41
votes

I am new to Fluent NHibernate and have been unable to figure out how to map composite keys.

How can I do this? What approach do I need to take?

4

4 Answers

52
votes

There's a CompositeId method.

public class EntityMap : ClassMap<Entity>
{
  public EntityMap()
  {
      CompositeId()
      .KeyProperty(x => x.Something)
      .KeyReference(x => x.SomethingElse);
  }
}
5
votes

if this is your first class

public class EntityMap : ClassMap<Entity>
{
  public EntityMap()
  {
    UseCompositeId()
      .WithKeyProperty(x => x.Something)
      .WithReferenceProperty(x => x.SomethingElse);
  }
}

here is the second with a reference on Entity

public class SecondEntityMap : ClassMap<SecondEntity>
    {
      public SecondEntityMap()
      {
        Id(x => x.Id);

        ....

        References<Entity>(x => x.EntityProperty)
          .WithColumns("Something", "SomethingElse")
          .LazyLoad()
          .Cascade.None()
          .NotFound.Ignore()
          .FetchType.Join();

      }
    }
5
votes

Another thing to note is that you must override the Equals and GetHashCode methods for an entity using a CompositeId. Given the accepted answers mapping file, your entity would look like this.

public class Entity
{
   public virtual int Something {get; set;}
   public virtual AnotherEntity SomethingElse {get; set;}


   public override bool Equals(object obj)
    {
        var other = obj as Entity;

        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return other.SomethingElse == SomethingElse && other.Something == Something;
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return (SomethingElse.GetHashCode()*397) ^ Something;
        }
    }

}
1
votes

There may be a need for entities with composite identifiers, entities that map to tables which have composite primary keys, composed of many columns. The columns that make up this primary key are usually foreign keys to another tables.

public class UserMap : ClassMap<User>
{      
   public UserMap()
   {
        Table("User");

        Id(x => x.Id).Column("ID");

        CompositeId()
          .KeyProperty(x => x.Id, "ID")
          .KeyReference(x => x.User, "USER_ID");

        Map(x => x.Name).Column("NAME");               

        References(x => x.Company).Column("COMPANY_ID").ForeignKey("ID");
    }
}

For more reference : http://www.codeproject.com/Tips/419780/NHibernate-mappings-for-Composite-Keys-with-associ