在 nhibernate 中删除具有多对多关系的实体时,不会删除该关系
When deleting an entity with many to many relationship in nhibernate the relationship is not deleted
我正在使用 NHibernate 和 C#。
我有两个实体,它们之间存在多对多关系。
当我删除父实体时,我只有它的 ID,我用 hql 查询删除它。
我的问题是它只删除父实体而不删除它的关系。
我的实体看起来像这样:
public class Entity_A
{
public virtual int Code { get; set; }
public virtual int Id { get; set; }
public virtual ICollection<Entity_B> Entities_B { get; set; }
}
public class Entity_B
{
public virtual int Code { get; set; }
public virtual ICollection<Entity_A> Entities_A { get; set; }
}
映射
public class EntityAMap : ClassMap<Entity_A>
{
public EntityAMap()
{
Table("ENTITY_A");
Id(x=>x.Code).GeneratedBy.Identity();
Map(x=>x.Id).column("A_ID").Not.Nullable();
HasManyToMany(x->x.Entities_B)
.LazyLoad()
.Generic()
.PropertyRef("Id")
.ChildKeyColumn("B_CODE")
.ParentKeyColumn("A_ID")
.Table("ENTITY_A_TO_ENTITY_B")
.Cascade.All();
}
}
public class EntityBMap : ClassMap<Entity_B>
{
public EntityBMap()
{
Table("ENTITY_B");
Id(x=>x.Code).GeneratedBy.Identity();
HasManyToMany(x->x.Entities_A)
.Generic()
.ChildPropertyRef("Code")
.ChildKeyColumn("A_ID")
.ParentKeyColumn("B_CODE")
.Table("ENTITY_A_TO_ENTITY_B")
.Cascade.All()
.Inverse();
}
}
我的问题是,我应该更改什么,以便当我使用 NHibernate HQL 查询删除 Entity_A 时,它也会删除它与 Entity_B 的所有关系(来自 table ENTITY_A_TO_ENTITY_B).
如果您的代码看起来像这样:
ISession session = sessionFactory.OpenSession();
ITransaction tx = session.BeginTransaction();
String hqlDelete = "delete Entity_A ea where ea.Code = :code";
int deletedEntities = session.CreateQuery( hqlDelete )
.SetString( "code", codeToDelete )
.ExecuteUpdate();
tx.Commit();
session.Close();
(所以如果代码看起来像上面那样)那么:
- 我们不使用 HQL 作为将实体加载到会话中的方式(并让 NHibernate 施展魔法)-
- 但我们使用的是所谓的 DML
查看文档:
13.3. DML-style operations
As already discussed, automatic and transparent object/relational mapping is concerned with the management of object state. This implies that the object state is available in memory, hence manipulating (using the SQL Data Manipulation Language (DML) statements: INSERT, UPDATE, DELETE) data directly in the database will not affect in-memory state...
主要是答案:...不会影响内存状态...
简单地说,通过这种方式,我们在使用 HQL 时仅使用 DML 有效地发出 WRITE 语句(查询语言在我们的实体之上,而不是SQL)
解决方案:
1) 将实例加载到内存中。我们可以使用 HQL,或 QueryOver,ICriteria...这里重要的是加载到内存中,响应到 ISession
这样,DELETE 上的 NHiberante 就可以开始发布所有预期的级联...
2) 使用 .CreateSQLQuery() 手动删除其余部分:
session
.CreateSQLQuery("DELTE FROM ENTITY_A_TO_ENTITY_B WHERE ENTITY_A = :id)
.SetString( "id", idToDelete )
.ExecuteUpdate();
...
session.CreateQuery( hqlDelete )
此 (第二种方法) 将支持有效的 SQL 语句 (无需将实例加载到会话中),但我们这边需要更多编码 (NHibernate 可以仅通过其会话施法)
我正在使用 NHibernate 和 C#。 我有两个实体,它们之间存在多对多关系。 当我删除父实体时,我只有它的 ID,我用 hql 查询删除它。
我的问题是它只删除父实体而不删除它的关系。
我的实体看起来像这样:
public class Entity_A
{
public virtual int Code { get; set; }
public virtual int Id { get; set; }
public virtual ICollection<Entity_B> Entities_B { get; set; }
}
public class Entity_B
{
public virtual int Code { get; set; }
public virtual ICollection<Entity_A> Entities_A { get; set; }
}
映射
public class EntityAMap : ClassMap<Entity_A>
{
public EntityAMap()
{
Table("ENTITY_A");
Id(x=>x.Code).GeneratedBy.Identity();
Map(x=>x.Id).column("A_ID").Not.Nullable();
HasManyToMany(x->x.Entities_B)
.LazyLoad()
.Generic()
.PropertyRef("Id")
.ChildKeyColumn("B_CODE")
.ParentKeyColumn("A_ID")
.Table("ENTITY_A_TO_ENTITY_B")
.Cascade.All();
}
}
public class EntityBMap : ClassMap<Entity_B>
{
public EntityBMap()
{
Table("ENTITY_B");
Id(x=>x.Code).GeneratedBy.Identity();
HasManyToMany(x->x.Entities_A)
.Generic()
.ChildPropertyRef("Code")
.ChildKeyColumn("A_ID")
.ParentKeyColumn("B_CODE")
.Table("ENTITY_A_TO_ENTITY_B")
.Cascade.All()
.Inverse();
}
}
我的问题是,我应该更改什么,以便当我使用 NHibernate HQL 查询删除 Entity_A 时,它也会删除它与 Entity_B 的所有关系(来自 table ENTITY_A_TO_ENTITY_B).
如果您的代码看起来像这样:
ISession session = sessionFactory.OpenSession();
ITransaction tx = session.BeginTransaction();
String hqlDelete = "delete Entity_A ea where ea.Code = :code";
int deletedEntities = session.CreateQuery( hqlDelete )
.SetString( "code", codeToDelete )
.ExecuteUpdate();
tx.Commit();
session.Close();
(所以如果代码看起来像上面那样)那么:
- 我们不使用 HQL 作为将实体加载到会话中的方式(并让 NHibernate 施展魔法)-
- 但我们使用的是所谓的 DML
查看文档:
13.3. DML-style operations
As already discussed, automatic and transparent object/relational mapping is concerned with the management of object state. This implies that the object state is available in memory, hence manipulating (using the SQL Data Manipulation Language (DML) statements: INSERT, UPDATE, DELETE) data directly in the database will not affect in-memory state...
主要是答案:...不会影响内存状态...
简单地说,通过这种方式,我们在使用 HQL 时仅使用 DML 有效地发出 WRITE 语句(查询语言在我们的实体之上,而不是SQL)
解决方案:
1) 将实例加载到内存中。我们可以使用 HQL,或 QueryOver,ICriteria...这里重要的是加载到内存中,响应到 ISession
这样,DELETE 上的 NHiberante 就可以开始发布所有预期的级联...
2) 使用 .CreateSQLQuery() 手动删除其余部分:
session
.CreateSQLQuery("DELTE FROM ENTITY_A_TO_ENTITY_B WHERE ENTITY_A = :id)
.SetString( "id", idToDelete )
.ExecuteUpdate();
...
session.CreateQuery( hqlDelete )
此 (第二种方法) 将支持有效的 SQL 语句 (无需将实例加载到会话中),但我们这边需要更多编码 (NHibernate 可以仅通过其会话施法)