ror*_*.ap 5 .net c# nhibernate many-to-one nhibernate-mapping-by-code
这个问题的变化已被要求,并回答了很多次,答案有很多重叠的细节.我已经尝试过这些答案提出的许多不同的事情,但是没有一个在我的案例中有效.
我有一个带有父表和子表的SQLite数据库.这是一个非常简单的设置.我正在使用NHibernate 4.0.4进行代码映射而不是流畅,因为我建议前者是新的,而后者是改进的.
实体:
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
}
Run Code Online (Sandbox Code Playgroud)
BillingItem映射:
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
}
}
Run Code Online (Sandbox Code Playgroud)
PaymentItem映射:
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.
}
}
Run Code Online (Sandbox Code Playgroud)
仓库:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
商业逻辑:
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);
Run Code Online (Sandbox Code Playgroud)
正如建议这个答案(和这个和这个和许多其他人),我已经确定设置Inverse(true)
在我的Set
(子集)中BillingItemMapping
.我还在对象中设置了双向引用PaymentItem
:
OwningBillingItem = bi
Run Code Online (Sandbox Code Playgroud)
和BillingItem
对象:
bi.PaymentItems.Add(pi);
Run Code Online (Sandbox Code Playgroud)
我觉得我已经按照它应该的方式设置了所有其他内容,并且我根据各种其他来源的建议对许多映射设置进行了修改.但是,我只是想不通为什么它不起作用.
问题是,我无法获取记录中的外键列PaymentItem
来保存ID BillingItem
.如果我将列设置为不允许空值(这应该是它的方式),我得到一个空约束异常.如果我将其设置为允许空值(用于测试),它只是设置为null(显然).
我究竟做错了什么?
呵呵,你的有问题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.
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
638 次 |
最近记录: |