FluentNHibernate 棘手的映射

发布于 2024-12-18 15:58:18 字数 2839 浏览 3 评论 0原文

当我加载数据时,所有内容都已正确映射和加载,但是当我尝试使用 PeriodPaymentTypeCalendarEntry 插入对象图时,它会引发异常:

{"Cannot insert the value NULL into column 'PaymentTypeId', table 'CashFlowCalculator.dbo.CalendarEntries'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."}

原因是尝试插入的对象的外键列没有值。我不知道我的映射错误在哪里?

对象

public class Period
{
    public virtual int Id { get; private set; }
    public virtual DateTime StartDate { get; set; }
    public virtual DateTime EndDate { get; set; }
    public virtual double OpeningCash { get; set; }
    public virtual IList<CalendarEntry> CalendarEntries { get; set; }

    public Period()
    {
        CalendarEntries = new List<CalendarEntry>();
    }
}

public class PaymentType
{
    public virtual int Id { get; private set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual DateTime StartDate { get; set; }
    public virtual DateTime EndDate { get; set; }
    public virtual bool IsIncome { get; set; }
    public virtual IList<CalendarEntry> CalendarEntries { get; set; }

    public PaymentType()
    {
        CalendarEntries = new List<CalendarEntry>();
    }
}
public class CalendarEntry
{
    public virtual int Id { get; private set; }
    public virtual double Amount { get; set; }
    public virtual DateTime DueDate { get; set; }
    public virtual PaymentType PaymentType { get; set; }
    public virtual Period Period { get; set; }

    public CalendarEntry(){ }

    public virtual void AddPaymentType(PaymentType paymentType)
    {
        paymentType.CalendarEntries.Add(this);
        PaymentType = paymentType;
    }

    public virtual void AddPeriod(Period period)
    {
        period.CalendarEntries.Add(this);
        Period = period;
    }
}

映射

public PeriodMap()
    {
        Table("Periods");
        Id(x => x.Id);
        Map(x => x.OpeningCash);
        Map(x => x.StartDate);
        Map(x => x.EndDate);
        HasMany(x => x.CalendarEntries).LazyLoad().Inverse().Cascade.All();
    }

public PaymentTypeMap()
    {
        Table("PaymentTypes");
        Id(x => x.Id);
        Map(x => x.Name);
        Map(x => x.Description);
        Map(x => x.StartDate);
        Map(x => x.EndDate);
        Map(x => x.IsIncome);
        HasMany(x => x.CalendarEntries).LazyLoad().Inverse().Cascade.All();
    }

public CalendarEntryMap()
    {
        Table("CalendarEntries");
        Id(x => x.Id);
        Map(x => x.Amount);
        Map(x => x.DueDate);
        References(x => x.PaymentType).Column("PaymentTypeId");
        References(x => x.Period).Column("PeriodId");
    }

When I load data everything is mapped and loaded correctly, but when I try to insert object graph with Period, PaymentType and CalendarEntry it throws an exception:

{"Cannot insert the value NULL into column 'PaymentTypeId', table 'CashFlowCalculator.dbo.CalendarEntries'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."}

The reason is that there is no value for the foreign key column of the object that tries to insert. I can't where is the mistake in my mappings?

Objects

public class Period
{
    public virtual int Id { get; private set; }
    public virtual DateTime StartDate { get; set; }
    public virtual DateTime EndDate { get; set; }
    public virtual double OpeningCash { get; set; }
    public virtual IList<CalendarEntry> CalendarEntries { get; set; }

    public Period()
    {
        CalendarEntries = new List<CalendarEntry>();
    }
}

public class PaymentType
{
    public virtual int Id { get; private set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual DateTime StartDate { get; set; }
    public virtual DateTime EndDate { get; set; }
    public virtual bool IsIncome { get; set; }
    public virtual IList<CalendarEntry> CalendarEntries { get; set; }

    public PaymentType()
    {
        CalendarEntries = new List<CalendarEntry>();
    }
}
public class CalendarEntry
{
    public virtual int Id { get; private set; }
    public virtual double Amount { get; set; }
    public virtual DateTime DueDate { get; set; }
    public virtual PaymentType PaymentType { get; set; }
    public virtual Period Period { get; set; }

    public CalendarEntry(){ }

    public virtual void AddPaymentType(PaymentType paymentType)
    {
        paymentType.CalendarEntries.Add(this);
        PaymentType = paymentType;
    }

    public virtual void AddPeriod(Period period)
    {
        period.CalendarEntries.Add(this);
        Period = period;
    }
}

Mappings

public PeriodMap()
    {
        Table("Periods");
        Id(x => x.Id);
        Map(x => x.OpeningCash);
        Map(x => x.StartDate);
        Map(x => x.EndDate);
        HasMany(x => x.CalendarEntries).LazyLoad().Inverse().Cascade.All();
    }

public PaymentTypeMap()
    {
        Table("PaymentTypes");
        Id(x => x.Id);
        Map(x => x.Name);
        Map(x => x.Description);
        Map(x => x.StartDate);
        Map(x => x.EndDate);
        Map(x => x.IsIncome);
        HasMany(x => x.CalendarEntries).LazyLoad().Inverse().Cascade.All();
    }

public CalendarEntryMap()
    {
        Table("CalendarEntries");
        Id(x => x.Id);
        Map(x => x.Amount);
        Map(x => x.DueDate);
        References(x => x.PaymentType).Column("PaymentTypeId");
        References(x => x.Period).Column("PeriodId");
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ゃ人海孤独症 2024-12-25 15:58:18

如果您希望 CalendarEntry 映射上的 PaymentType 属性为“可为空”,我认为您必须指定它:

public CalendarEntryMap()
{
    Table("CalendarEntries");
    Id(x => x.Id);
    Map(x => x.Amount);
    Map(x => x.DueDate);
    References(x => x.PaymentType).Column("PaymentTypeId").Nullable();
    References(x => x.Period).Column("PeriodId");
}

相反,如果您不希望它为空,则必须手动设置任何 CalendarEntry 实例的 PaymentType 属性。

If you want a "nullable" PaymentType property of your on your CalendarEntry mapping, I think you have to specify it:

public CalendarEntryMap()
{
    Table("CalendarEntries");
    Id(x => x.Id);
    Map(x => x.Amount);
    Map(x => x.DueDate);
    References(x => x.PaymentType).Column("PaymentTypeId").Nullable();
    References(x => x.Period).Column("PeriodId");
}

Instead, if you don't want it nullable, you have to manually set the PaymentType property of any CalendarEntry instance.

夜吻♂芭芘 2024-12-25 15:58:18

这是我用来设置对象图的代码:

Period period = new Period
{
    OpeningCash = 2000,
    StartDate = new DateTime(2011, 1, 1),
    EndDate = new DateTime(2011, 12, 1)
};

PaymentType type = new PaymentType
{
    Description = "Description",
    IsIncome = false,
    Name = "Name",
    StartDate = new DateTime(2010, 11, 23),
    EndDate = new DateTime(2012, 11, 23)
};

CalendarEntry entry = new CalendarEntry 
{
    Amount = 232,
    DueDate = new DateTime(2011, 7, 23)
};
entry.AddPeriod(period);
entry.AddPaymentType(type);

This is the code that I use to set the object graph:

Period period = new Period
{
    OpeningCash = 2000,
    StartDate = new DateTime(2011, 1, 1),
    EndDate = new DateTime(2011, 12, 1)
};

PaymentType type = new PaymentType
{
    Description = "Description",
    IsIncome = false,
    Name = "Name",
    StartDate = new DateTime(2010, 11, 23),
    EndDate = new DateTime(2012, 11, 23)
};

CalendarEntry entry = new CalendarEntry 
{
    Amount = 232,
    DueDate = new DateTime(2011, 7, 23)
};
entry.AddPeriod(period);
entry.AddPaymentType(type);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文