【问题标题】:Remove entity in NHibernate only by primary key仅通过主键删除 NHibernate 中的实体
【发布时间】:2010-10-07 10:27:30
【问题描述】:

我正在尝试实现一种仅使用主键删除实体的存储库方法,主要是因为从 web 应用程序中,我通常只在从网页调用“删除请求”时才知道主键。

由于 ORM,今天的选择是从数据库中获取实体,然后将其删除,这给了我额外的往返。

我可以使用 HQL 删除,但由于我想为所有实体创建一个通用的删除方法,除非我使用反射找出哪个字段是主键(可行,但感觉不到正确)。

或者 NHibernate 的本质是需要实体才能正确处理级联?

我尝试了这种方法,假设它不会加载实体,除非明确需要,但还没有时间测试它。也许有人可以阐明如何处理?

var entity = session.Load<T>( primaryKey );
session.Delete( entity );

编辑:现在已经对其进行了测试,似乎它仍然在删除之前对实体进行了完全选择。

【问题讨论】:

标签: c# nhibernate


【解决方案1】:

Load 可能会返回一个代理对象,但不能保证。您的映射可能包含级联删除,这将强制 NHibernate 从数据库中加载对象以确定如何删除对象及其图形。

我会像你一样使用 Load 来实现这个。对于某些对象,NHibernate 可能不需要先进行选择。在这种情况下,这就是您使用 o/r 映射器所付出的 [通常] 微不足道的代价。

【讨论】:

  • 我一直在试图弄清楚它什么时候会返回一个代理对象。你知道它是否只返回定义为“惰性”的类的代理?
  • 我不知道,但我的猜测是,如果映射包含任何级联设置,它将加载对象。这是一个不错的功能——您无需担心清理相关对象。除非出现性能问题,否则我会忍受这种行为。通过主键加载对象通常是一个非常快速的操作。
【解决方案2】:
【解决方案3】:

nHibernate 是一个 O(bject)RM。我同意你的观点,它可能需要对象来解决依赖关系。

您当然可以使用直接 ADO.Net 调用来删除您的对象。这当然会带来自己的问题,因为您必须自己处理任何级联问题。如果您确实走这条路,请不要忘记从 nHibernate 会话中逐出您使用此方法删除的任何对象。

但是,如果这个删除是在你系统的一个非常敏感的部分,那可能是要走的路。

尽管情况确实如此,但我会 100% 确定。扔掉所有的 nHibernate 给你,因为这样是不明智的。

我感觉你知道这一点,并且你正在寻找一个严格的 nHibernate 答案,我认为它不存在,抱歉。

【讨论】:

    【解决方案4】:

    免责声明:我目前无法对其进行测试。但不会跟随事情帮助:

    Person entity = new Person();
    entity.Id = primaryKey;
    session.Delete( entity );
    

    不要加载实体,而是构建只有主键的实体。我很想对其进行测试,但现在我的环境无法正常工作。

    【讨论】:

    • 这可能有效,但它可能会拒绝删除与会话无关的对象。对我来说问题是,并非所有实体都将 .Id 作为其主键,我需要反思以找出哪个是什么,而不是我认为的漂亮解决方案。不过感谢您的建议。
    猜你喜欢
    • 1970-01-01
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多