我一直试图掌握Hibernate的逆属性,它似乎只是概念上难以解决的问题之一.
我得到的要点是,当你有一个使用一对多映射的Child对象集合的父实体(例如Parent)时,在映射上设置inverse = true告诉Hibernate'另一边(Child) )有责任更新自己以维护其表中的外键引用'.
这样做对于在代码中向集合中添加Children,然后保存Parent(使用cascade-all set)有两个好处:在数据库上保存一个不必要的命中(因为没有逆集,Hibernate认为它有两个地方更新FK关系),并根据官方文档:
如果关联的列被声明为NOT NULL,则NHibernate在创建或更新关联时可能会导致约束违规.要防止出现此问题,必须使用标记为inverse ="true"的多值结束(集合或包)的双向关联.
到目前为止,这一切似乎都有意义.我不明白是这样的:你什么时候会不希望使用逆=真正在一个一对多的关系?
我有两个表,tableA和tableB.
tableA有列:tabAId,col2,col3 (tabAId primaryKey和Identity列.)
tableB有列:tabAId,name (tabAId不为null)
我在tableA的hbm文件中创建了Bag,以维护关系.
<bag name="tableB" lazy="true" inverse="false"
batch-size="25" cascade="all-delete-orphan">
<key column="tabAId" />
<one-to-many class="tableB" />
</bag>
Run Code Online (Sandbox Code Playgroud)
当我尝试更新tableA中的记录时,它抛出异常,因为我在tableA实例中有子列表.
[NHibernate.Exceptions.GenericADOException] = {"无法删除集合:[MIHR.Entities.tableA.tableB#21] [SQL:UPDATE dbo.tableB SET tabAId = null WHERE tabAId = @ p0]"}
InnerException = {"无法将值NULL插入列'tabAId',表'SA_MIHR_DEV.dbo.tableB';列不允许空值.UPDATE失败.\ r \n语句已终止."}
这个问题的变化已被要求,并回答了很多次,答案有很多重叠的细节.我已经尝试过这些答案提出的许多不同的事情,但是没有一个在我的案例中有效.
我有一个带有父表和子表的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> …Run Code Online (Sandbox Code Playgroud) 我需要加载一个包含很多孩子和孩子孩子的非常大的物品清单.什么是最好的方法?
我正在使用Oracle 11g数据库,我编写了以下方法,但它产生了笛卡尔积(重复结果):
public IList<ARNomination> GetByEventId(long eventId)
{
var session = this._sessionFactory.Session;
var nominationQuery = session.Query<ARNomination>().Where(n => n.Event.Id == eventId);
using (var trans = session.Transaction)
{
trans.Begin();
// this will load the Contacts in one statement
nominationQuery
.FetchMany(n => n.Contacts)
.ToFuture();
// this will load the CustomAttributes in one statement
nominationQuery
.FetchMany(n => n.CustomAttributes)
.ToFuture();
// this will load the nominations but joins those two tables in one statement which results in cartesian product
nominationQuery
.FetchMany(n => n.CustomAttributes)
.FetchMany(n => …Run Code Online (Sandbox Code Playgroud) nhibernate ×4
c# ×2
hibernate ×2
.net ×1
collections ×1
future ×1
hbm ×1
inverse ×1
many-to-one ×1
one-to-many ×1
orm ×1