Fluent Nhibernates 在 for 循环中加载整个对象依赖项

Fluent Nhibernates loads the whole object dependencies in a for loop

我正在使用 NHibernate ORM 的 C# 项目中工作。我对这个框架很陌生。

我有以下 table 映射:

this.Table("FCT_CONNECTR_TRANSF_MAP_CONCEP");
this.LazyLoad();
this.Id(x => x.Id).GeneratedBy.TriggerIdentity().Column("ID_CONNECTR_TRANSF_MAP_CONCEP");
this.References(x => x.ConnectorTransformation).Not.Nullable().Column("ID_CONNECTOR_TRANSFORMATION");
this.References(x => x.LookUpConcept).Nullable().Column("ID_MAP_CONCEPT").Cascade.All();
this.References(x => x.MapCustomSource).Column("ID_MAP_CUSTOM_SOURCE").Cascade.All();
this.References(x => x.MapCustomTarget).Column("ID_MAP_CUSTOM_TARGET").Cascade.All();
this.References(x => x.CreatedBy).Nullable().Column("CREATED_BY");
this.References(x => x.ModifiedBy).Column("MODIFIED_BY");
this.Map(x => x.DtCreated).Nullable().Column("DT_CREATED");
this.Map(x => x.DtModified).Column("DT_MODIFIED");
this.Map(x => x.Description).Column("DSC_MAP_CONCEPT");

在我的 C# 代码中,我有以下代码片段。

foreach (var mapConcept in mapConcepts)
{
    this.connectorTransformationMapConceptEntityRepository.Delete(mapConcept);
}

线上this.connectorTransformationMapConceptEntityRepository.Delete(mapConcept); ORM 加载所有依赖项(+5000 select 查询)。

我的问题:为什么 NHibernate 需要解析所有依赖关系才能删除对象?

原因是级联,当你删除parent时,所有的child都会被删除等等

如果您不想级联删除,您可能需要从 .Cascade().All() 更改为 .Cascade().SaveUpdate()

您可以在 ayende.com

找到更多关于级联行为的信息

有映射 .Cascade.All() 应用于您的 many-to-one 参考映射。 cascade 设置指示 NHibernate:“加载相关数据并在删除时删除它们”。

这就是为什么 NHibernate 必须加载相关内容的原因。如果级联是我们需要的功能——我们可以使用一些优化,批量获取:

19.1.5. Using batch fetching

NHibernate can make efficient use of batch fetching, that is, NHibernate can load several uninitialized proxies if one proxy is accessed (or collections. Batch fetching is an optimization of the lazy select fetching strategy. There are two ways you can tune batch fetching: on the class and the collection level.

Batch fetching for classes/entities is easier to understand. Imagine you have the following situation at runtime: You have 25 Cat instances loaded in an ISession, each Cat has a reference to its Owner, a Person. The Person class is mapped with a proxy, lazy="true". If you now iterate through all cats and call cat.Owner on each, NHibernate will by default execute 25 SELECT statements, to retrieve the proxied owners. You can tune this behavior by specifying a batch-size in the mapping of Person:

<class name="Person" batch-size="10">...</class>

NHibernate will now execute only three queries, the pattern is 10, 10, 5.

因此,我们可以使用批量大小扩展 类 MapCustomSourceMapCustomTarget 的映射:

Table(...)
Id(...)
BatchSize(25)

或者我们甚至可以改变方法并使用一些更有效的方法来删除更多项目而不加载它们:

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. However, NHibernate provides methods for bulk SQL-style DML statement execution which are performed through the Hibernate Query Language (HQL).

完全没有加载的代码删除示例:

ISession session = sessionFactory.OpenSession();
ITransaction tx = session.BeginTransaction();

String hqlDelete = "delete Customer c where c.name = :oldName";
// or String hqlDelete = "delete Customer where name = :oldName";
int deletedEntities = s.CreateQuery( hqlDelete )
        .SetString( "oldName", oldName )
        .ExecuteUpdate();
tx.Commit();
session.Close();