title: Fluent NHibernate Mapping Compent with Many-To-Many and Extra Fields
body: <p>I have been spinning around in the same place trying to figure this issue with a many-to-many table with extra columns. I am swallowing my pride and asking more experienced Fluent NHibernate  experts if you can help out here.</p>
  
  <p>I have been trying to use a component for a many-to-many table but I don't seem to find where to point the component to cause a join on a specific column. I guess as long as I populate the completion information object, the presence and usage of a component is not a requirement for me.</p>
  
  <p>This is my simplified schema.</p>
  
  <pre><code>User
  ...................
  Id
  Name 
  
  Task
  ...................
  Id
  Name
  
  
  Job
  ...................
  Id
  Name
  
  JobTask
  ...................
  JobId
  TaskId
  CompletedByUserId
  CompletionDate
  CompletionNotes
  </code></pre>
  
  <p>Then I have objects like so:</p>
  
  <pre><code> public class Job
   {
      long Id { get; set; }
      IList&lt;Task&gt; Tasks { get; set; }
   }
  
  
   public class Task
   {
      long Id { get; set; }
      string Name { get; set; }
      CompletionInfo CompletionInfo { get; set; }
   }
  
   public class CompletionInfo
   {
      User User { get; set; }
      DateTime CompletionDate { get; set; }
   }
  </code></pre>
  
  <p>Can you help with your ideas how to implement this in fluent nhibernate?</p>
  
  <p>I had this mapping before on the JobMap and it would work but only for the many-to-many columns ( TaskId, JobId). I need the extra information related to that relationship(dateCompleted, userCompleted,etc)</p>
  
  <pre><code> HasManyToMany&lt;Task&gt;(job =&gt; job.Tasks)
              .Table(ManyToManyTable)
               .ParentKeyColumn("JobId")
              .ChildKeyColumn("TaskId")
              .Not.LazyLoad()
              .Cascade.Delete();
  </code></pre>
  
  <p>In order to simplify things with the many-to many I thought to create an object to represent the relationship and encapsulate a task. Like so:
  And I would add a proxy in the Job task to modify the actual Task properties. But that is not going anywhere.</p>
  
  <p>This must be something common out there, I am very surprised there not much regarding this issue. 
  Naturally I would have loved a way to extend the HasManyToMany but not sure how, hence this post.</p>
  
  <pre><code>public class JobTask : Entity&lt;long, JobTask&gt;
  { 
      public virtual Job ParentJob { get; set; }
  
      public virtual Task Task   { set;set; }
  
      public virtual TaskCompletionDetails CompletionInformation
      {
          get
          {
              if (this.Task == null)
                  return null;
  
              return Task.CompletionInformation;
          }
  
          set
          {
              if (this.Task == null)
                  return;
  
              this.Task.CompletionInformation = value;
          }
      }
  
  
      public virtual string CompletionNotes
      {
          get
          {
              if (this.Task == null || this.Task.CompletionInformation == null)
                  return null;
  
              return Task.CompletionInformation.Notes;
          }
  
          set
          {
              if (this.Task == null)
                  return;
  
              this.Task.CompletionInformation.Notes = value;
          }
      }
  
      public virtual DateTime? CompletionDate
      {
          get
          {
              if (this.Task == null || this.Task.CompletionInformation == null)
                  return null;
  
              return Task.CompletionInformation.Date;
          }
  
          set
          {
              if (this.Task == null)
                  return;
  
              this.Task.CompletionInformation.Date = value;
          }
      }
  
      public virtual IUser User
      {
          get
          {
              if (this.Task == null || this.Task.CompletionInformation == null)
                  return null;
  
              return Task.CompletionInformation.User;
          }
  
          set
          {
              if (this.Task == null || value == null)
                  return;
  
              if (this.Task.CompletionInformation != null)
                  this.Task.CompletionInformation.User = value;
          }
         }
      }
   }
  </code></pre>
  
  <p>This would be the map direction I have started for it:</p>
  
  <pre><code>public class JobTaskMap : ClassMap&lt;JobTask&gt;
  {
      private const string ModelTable = "[JobTasks]";
  
      public JobTaskMap()
      {
          Table(ModelTable);
  
          Id(jobTask =&gt; jobTask.Id)
              .Column("Id")
              .GeneratedBy.Identity();
  
          References&lt;Job&gt;( jobTask =&gt; jobTask.ParentJob)
              .Column("JobId")
              .Fetch.Join();
  
          Component&lt;Task&gt;( jobTask =&gt; (Task) jobTask.Task,
                  // This is the task
                   comp =&gt;
                   { 
                       // This is the task completion information
                       comp.Component&lt;TaskCompletionDetails&gt;(
                           task =&gt; (TaskCompletionDetails)task.CompletionInformation,
                           compInfo =&gt;
                           {    
                               compInfo.Map(info =&gt; info.Date)
                                  .Column("CompletionDate")
                                  .Nullable();
  
                               compInfo.Map(info =&gt; info.Notes)
                                  .Column("CompletionNotes")
                                  .Nullable();
  
                               compInfo.References&lt;User&gt;(info =&gt; info.User)
                                  .Column("CompletedByUserId")
                                  .Nullable()
                                  .Fetch.Join();
                           });  
                   });
  
      }
  </code></pre>
  
  <p>These are some other related reading I have followed without success:</p>
  
  <p>Reference:</p>
  
  <p><a href="http://wiki.fluentnhibernate.org/Fluent_mapping" rel="nofollow noreferrer">http://wiki.fluentnhibernate.org/Fluent_mapping</a> </p>
  
  <p><a href="https://stackoverflow.com/questions/2455473/fluent-nhibernate-many-to-many-mapping-with-extra-column">Fluent Nhibernate Many-to-Many mapping with extra column</a></p>