gpt4 book ai didi

c# - 通过代码映射的 NHibernate 和 SQLite 数据库 : saving many-to-one parent-child entities, 子项获取空外键

转载 作者:太空狗 更新时间:2023-10-29 23:29:15 25 4
gpt4 key购买 nike

这个问题的变体已经被问过和回答过很多 次,答案有很多重叠的细节。我已经尝试了这些答案所建议的许多不同的方法,但在我的案例中没有一个起作用。

我有一个带有父表和子表的 SQLite 数据库。这是一个非常简单的设置。我使用 NHibernate 4.0.4 通过代码映射而不是像 it was suggested to me that the former is newer and an improvement over the latter 那样流畅.

实体:

public class BillingItem
{
public virtual int ID { get; set; }
public virtual string Name { get; set; }
// ... other properties
public virtual ICollection<PaymentItem> PaymentItems { get; set; }

public BillingItem()
{
PaymentItems = new List<PaymentItem>();
}
}

public class PaymentItem
{
public virtual int ID { get; set; }
public virtual BillingItem OwningBillingItem { get; set; }
// ... other properties
}

计费项目映射:

public class BillingItemMapping : ClassMapping<BillingItem> 
{
public BillingItemMapping()
{
Table("BillingItems");
Lazy(true);
Id(x => x.ID, map => map.Generator(Generators.Identity));

Set(x => x.PaymentItems, c =>
{
c.Key(k =>
{
k.Column("ID");
k.ForeignKey("BillingItemID");
});
c.Inverse(true);
c.Cascade(Cascade.None);
},
r => r.OneToMany(o => { }));

Property(x => x.Name);
// ... other properties
}
}

付款项目映射:

public class PaymentItemMapping  : ClassMapping<PaymentItem> 
{
public PaymentItemMapping()
{
Table("PaymentItems");
Lazy(true);
Id(x => x.ID, map => map.Generator(Generators.Identity));

ManyToOne(x => x.OwningBillingItem, m =>
{
m.Column("ID");
m.Update(false);
m.Insert(false);
m.Cascade(Cascade.None);
m.Fetch(FetchKind.Join);
m.NotFound(NotFoundMode.Exception);
m.Lazy(LazyRelation.Proxy);
m.ForeignKey("BillingItemID");
});

Property(x => x.DueDate, map => map.NotNullable(true));
// ... other properties.
}
}

存储库:

public void Add(BillingItem toAdd)
{
using (ISession session = Helpers.NHibernateHelper.OpenSession())
using (ITransaction tran = session.BeginTransaction())
{
session.Save(toAdd);

foreach (var pi in toAdd.PaymentItems)
{
session.Save(pi);
}

tran.Commit();
}
}

业务逻辑:

var bi = new BillingItem()
{
Name = Guid.NewGuid().ToString(),
// ... others..
};

var pi = new PaymentItem()
{
OwningBillingItem = bi,
DueDate = DateTime.Now.AddDays(3)
// ... others..
};

bi.PaymentItems.Add(pi);
var repo = new Repository();
repo.Add(bi);

根据 this answer 的建议(以及 thisthis 以及许多其他),我确保在 Set(子集合)中设置 Inverse(true) 计费项目映射。我还在 PaymentItem 对象中设置了我的双向引用:

OwningBillingItem = bi

BillingItem对象:

bi.PaymentItems.Add(pi);

我觉得我已经按照应有的方式设置了所有其他内容,并且我已经根据其他各种来源的建议修改了许多映射设置。但是,我只是想不通为什么它不起作用。

问题是,我无法获取 PaymentItem 记录中的外键列来保存 BillingItem 中的 ID。如果我将列设置为不允许空值(这是应该的方式),我会得到一个空约束异常。如果我将它设置为允许空值(用于测试),它只会被设置为空值(很明显)。

我做错了什么?

最佳答案

呵呵,你的PaymentItemMapping有问题,正确的映射应该是这样的:

public class PaymentItemMapping : ClassMapping<PaymentItem> {

public PaymentItemMapping() {
Table("PaymentItems");
Lazy(true);
Id(x => x.ID, map => map.Generator(Generators.Identity));

ManyToOne(x => x.OwningBillingItem, m => {
//Do not map to m.Column("ID");
m.Column("BillingItemID");
// BillingItemID can be insert and update
m.Update(true);
m.Insert(true);
m.Cascade(Cascade.None);
m.Fetch(FetchKind.Join);
m.NotFound(NotFoundMode.Exception);
m.Lazy(LazyRelation.Proxy);
m.ForeignKey("BillingItemID");
});

Property(x => x.DueDate, map => map.NotNullable(true));
// ... other properties.
}
}

关于c# - 通过代码映射的 NHibernate 和 SQLite 数据库 : saving many-to-one parent-child entities, 子项获取空外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39209164/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com