Search code examples
c#nhibernatenhibernate-mapping

what's wrong with my NHibernate mapping?


I have a table PayrollProcessingProgress which has as its primary key, the id of another table, PayrollPeriod. It is not a one-to-one mapping as a PayrollPeriod has either 1 or zero PayrollProcessingProgresses.

my mapping

public class PayrollProcessingProgressMap : ClassMap<PayrollProcessingProgress>
{
public PayrollProcessingProgressMap()
{
    Table("PayrollProcessingProgress");

     Id(x => x.PayrollPeriodId).GeneratedBy.Foreign("PayrollPeriodId");

    Map(x => x.RecordsProcessed);
}
}

for table

CREATE TABLE [dbo].[PayrollProcessingProgress](
    [PayrollPeriodId] [uniqueidentifier] NOT NULL,
    [RecordsProcessed] [int] NOT NULL,
 CONSTRAINT [PK_PayrollProcessingProgress] PRIMARY KEY CLUSTERED 
(
    [PayrollPeriodId] ASC
)
)

GO

ALTER TABLE [dbo].[PayrollProcessingProgress]  WITH CHECK ADD  CONSTRAINT [FK_PayrollProcessingProgress_PayrollPeriods] FOREIGN KEY([PayrollPeriodId])
REFERENCES [dbo].[PayrollPeriods] ([Id])
GO

ALTER TABLE [dbo].[PayrollProcessingProgress] CHECK CONSTRAINT [FK_PayrollProcessingProgress_PayrollPeriods]
GO

I can Read<> and update the number fields on the entities I've saved manually in the db successfully, but when I try to

Save(new PayrollProcessingProgress{
PayrollPeriodId = [Guid I know to be a valid payrollperiodid],
RecordsProcessed = 0
}

I get "Unable to resolve property: PayrollPeriodId"


Solution

  • you have to define a reference to the main entity to use the Id from or define it as simple keyreference

    public PayrollProcessingProgress
    {
        public virtual PayrollPeriod Period { get; set; }
        public virtual int RecordsProcessed { get; set; }
    }
    
    public PayrollProcessingProgressMap()
    {
        CompositeId().KeyReference(x => x.Period, "PayrollPeriodId");
    
        Map(x => x.RecordsProcessed);
    }
    

    another possibility is to map it as nullable property in the main class ans use join mapping. However you can not delete the RecordsProcessed record anymore

    public PayrollPeriod
    {
        ...
        public virtual int? RecordsProcessed { get; set; }
    }
    
    public PayrollPeriodMap()
    {
        Join("PayrollProcessingProgress", join => 
        {
            join.KeyColumn("PayrollPeriodId");
            join.Optional();
            join.Map(x => x.RecordsProcessed);
        });
    }