【问题标题】:Breaking changes with NHibernate 4 upgradeNHibernate 4 升级带来的重大变化
【发布时间】:2014-10-16 12:26:11
【问题描述】:

我可以在NHibernate 4.0 中查看新功能和已修复的内容

我想知道是否有人遇到过从 NHibernate 3 升级到 4 的 hbm 映射问题?

我担心这些天更多的注意力集中在流畅的地图上。我可以测试更明显的重大变化,但想知道是否有人在生产环境中遇到过任何一开始可能不那么明显的细微问题。

这看起来像是一次重大升级,您预计会有回归的风险。

【问题讨论】:

  • 一个公平的问题,但还是一个民意调查。
  • 一个公平的评论,我已经更准确地表达了我的担忧。我喜欢这个暂停功能,这是我第一次遇到,它比旧的简单关闭要好得多。

标签: c# nhibernate hbm nhibernate-3 nhibernate-4


【解决方案1】:

我不会太担心 hbm 本身。 FluentNHibernate “编译”为通过映射层的 XML。 NHibernate 自己的按代码映射也使用与 hbm 文件相同的部分代码。

无论如何,映射代码并没有太大变化。任何回归都更有可能出现在其他部分。

【讨论】:

    【解决方案2】:

    仅供参考,我发现抛出了一个新错误。我们使用按代码映射,我们曾经有一个实体,它有多个 Bag 映射,在 NHibernate v 3.3.x 中将 Fetch 类型设置为 Join。在 4.0.x 版本中不再允许这样做。

    我们收到了 Cannot simultaneously fetch multiple bags. 的错误消息,这与幕后必要的内容有关,但从技术上讲,它应该被视为重大更改。 NHibernate 不能很好地告诉我们是哪个映射导致了问题。

    【讨论】:

    • 好点,也打这个,但后来意识到这是一个很好的弃用。您的查询可能效率低下并带回大量数据表,请考虑使用期货。
    • 显然,Set 知道在同一批次中进行单独的查询,因此像Bags 这样的笛卡尔积应该不会有问题。
    • 同样使用按代码映射,我无法使枚举映射正常工作(使用 SQLite,如果这很重要)。它在保存期间工作正常,但使用 Get 检索不起作用 - 它似乎试图将字符串“System.Byte []”转换为枚举类型,这当然不起作用。在任何地方都找不到好的参考。
    • @jweyrich,我对枚举没有任何问题。我将一个类的 ID 属性映射到该列,仅此而已。工作正常。创建一个问题并将链接发送给我,我会看看是否可以提供帮助。
    • 使用 FluentNHibernate 它就像一个魅力。没有它就没有那么幸运了。无论如何,我现在已经切换到 Fluent。无论如何感谢您的支持。
    【解决方案3】:

    我们在相当大的QueryOver - Cannot simultaneously fetch multiple bags 中遇到了同样的问题,带有 Nhibernate 4 和 FluentNhibernate 映射。

    解决方案是在我们的 FluentMaps 上设置AsSet()(根据我们的支持字段),最终解决了这个问题。

    根据评论中的要求,以下是我们在异常之前和之后的映射的一个小示例:

    这是我们课程的一个非常简化的展示,它导致了Cannot simultaneously fetch multiple bags。抽象Entitybelongs to the S#Arp lite architecture。在更改之前它看起来像这样

    public class OrderHeader : Entity
    {
        public virtual IList<OrderItem> Items { get; set; }
    }
    
    public class OrderItem : Entity
    {
        public virtual decimal Price {get; set;}
        public virtual string ItemNumber {get; set;}
        public virtual OrderHeader Header {get; set;}
    }
    
    public class OrderHeaderMap : ClassMap<OrderHeader>
    {
        Id( e => e.Id).GeneratedBy.Native();
        HasMany(e => e.OrderItems).Inverse();
    }
    
    public class OrderItemMap : ClassMap<OrderItem>
    {
        Id(e => e.Id).GeneratedBy.Native();
        References(e => e.Header).Not.Nullable();
    }
    

    如您所见,OrderHeader 有一个IList 的项目。将其更改为

    public class OrderHeader : Entity
    {
        public virtual ISet<OrderItem> Items { get; set; } // ISet here
    }
    
    public class OrderItem : Entity
    {
        public virtual decimal Price {get; set;}
        public virtual string ItemNumber {get; set;}
        public virtual OrderHeader Header {get; set;}
    }
    
    public class OrderHeaderMap : ClassMap<OrderHeader>
    {
        Id( e => e.Id).GeneratedBy.Native();
        HasMany(e => e.OrderItems).Inverse();
    }
    
    public class OrderItemMap : ClassMap<OrderItem>
    {
        Id(e => e.Id).GeneratedBy.Native();
        References(e => e.Header).Not.Nullable().AsSet(); // Explicit AsSet
    }
    

    所以ISet 和映射上明确的AsSet() 使问题消失了。这段代码 sn-p 非常简化,我们在 QueryOverHasMany() IList 中有多个实体 - 当所有实体都更新为 ISet 时,它工作正常。

    【讨论】:

    • 您有旧/新映射示例吗?
    • @AlexeyZimarev 当然,我已经用之前和之后的示例更新了我的答案。希望这对您和其他任何人都有帮助:)
    猜你喜欢
    • 2022-05-17
    • 2010-10-04
    • 2015-01-26
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-15
    相关资源
    最近更新 更多