【问题标题】:Fluent-nhibernate: discriminate objects to load the hierrachy correctlyFluent-nhibernate:区分对象以正确加载层次结构
【发布时间】:2009-06-12 21:40:44
【问题描述】:

更新

好吧,正如 Stuart Charles 和 James Gregory 告诉我的,我的模型一开始就很奇怪。显然,在区分不同类型的关系时,类之间的双向引用并没有完成,而且显然是有充分理由的。

我拆掉了模型,在 Users 和 Fiches 之间使用 HasManyToMany 将其更改为不同的模型,然后我添加了一些编码验证以确保我的用户不能链接到多个 Fiche。

所以我想这类问题的答案是一种警告:“不要这样做”;)

感谢两位花时间回答!


大家好

正确使用 Fluent Nhibernate 是一条艰难的道路,而且由于我开始感到非常难过,我认为寻求帮助不会有什么坏处。事情是这样的。

罪魁祸首

我有以下两个类,Fiche 和 User。一个 Fiche 必须有一个 User 所有者,并且可以有许多 User 关注者。另一方面,用户可以选择链接回一个且只有一个 Fiche。 (EntityUpdateTrace 基类包含一个 guid id 和创建/修改时间,供 PreSave/PreUpdate 使用)

Public Class Fiche
    Inherits EntityUpdateTrace(Of Fiche)

    Private m_Owner As User
    Public Property Owner() As User
        ' snip

    Private m_Followers As IList(Of User)
    Public Property Followers() As IList(Of User)
        ' snip

End Class

Public Class User
    Inherits EntityUpdateTrace(Of User)

    Private m_Fiche As Fiche
    Public Property Fiche() As Fiche
        ' snip

End Class

然后我有以下映射

Public Class FicheMapping
Inherits ClassMap(Of Fiche)
Public Sub New()
    [Not].LazyLoad()
    Id(Function(f As Fiche) f.Id).GeneratedBy.GuidComb()
    References(Of User)(Function(f As Fiche) f.Owner).Not.Nullable()
    HasMany(Of User)(Function(f As Fiche) f.Followers).Inverse()
End Sub
End Class

Public Class UserMapping
    Inherits ClassMap(Of User)
    Public Sub New()
        [Not].LazyLoad()
        Id(Function(a As User) a.Id).GeneratedBy.GuidComb()
        References(Of Fiche)(Function(a As User) a.Fiche).Nullable()
    End Sub
End Class

问题

我到底做错了什么? :) 我似乎无法让这个模型工作,尽管它看起来很简单。

  • Fiche 加载与其相关的所有用户;听起来合乎逻辑,我想我应该区分一个特定的参数,但由于它完全与数据库相关,所以我不太喜欢这个想法(我试图保持课程干净整洁,作为域卫生方面的练习)。因此,如果 FicheveryImportantFiche 由 Alice 创建并由 Bob 跟随,则在重新加载关注者时,我会找到 Alice 和 Bob。有没有办法区分这两种类型的用户?

  • 我想在数据库中使用一个列表来保持关注者有序,但是一旦我将映射更改为

    HasMany(Of User)(Function(f As Fiche) f.Followers).AsList().Inverse()

弹出如下错误:

用于集合的空索引列: 追随者

关于这个错误的信息量并不是真的太多,这让我认为我对这个模型采取了错误的方式,这让我回到了第一个问题......我到底做错了什么?

感谢大家的阅读以及对此的任何见解!

【问题讨论】:

    标签: nhibernate fluent-nhibernate mapping


    【解决方案1】:

    List 错误是由于列表的语义而发生的。这很棘手,因为袋子默认情况下也会映射到 IList,但这是由于 .NET 框架中缺少具有“袋子”语义的集合类型。从概念上讲,在“袋子”中,没有顺序,因为物品只是被扔进袋子并以任何顺序取出,并且可以很容易地在袋子内移动。然而,列表本质上是有序和索引的(将其视为具有附加语义的数组,因此每个元素都有一个唯一的索引值)。您收到的错误消息表明 NHibernate 想要一个存储每个元素的索引值的列(因此它必须是唯一的,并且因为它是一个 IList,所以它是一个整数值)。由于您似乎没有索引列,因此您必须以另一种方式对它们进行排序,也许通过在查询中添加 ORDER BY 子句。

    至于第一个问题,您可能需要重新考虑如何处理这个问题。实际上,您也许可以利用NHibernate filters,但我没有任何经验可以告诉他们如何解决。您的Followers 集合实际上是与Fiche 相关的所有用户(所有引用FicheUsers),所以它更像RelatedUsers。使用存储库模式,您可以使用类似FindFollowers(Fiche fiche) 的方法来查询所有RelatedUsers,其中User 不等于Owner。由于您希望订购 Users,因此这种模式可能对您也有好处。类似(C#,条件查询):

    session.CreateCriteria(typeof(Fiche))
        .CreateCriteria("RelatedUsers", JoinType.InnerJoin)
            .Add(Restrictions.Not(Restrictions.Eq("Id", fiche.Owner.Id)))
            .AddOrder(Order.Asc("PropertyNameToOrderBy"))
            .List<User>();
    

    【讨论】:

    • 关于第一个问题,我真的不明白为什么列表的索引列应该是映射的 poco 类的责任,我觉得很奇怪......我不确定我是否理解完全地;从我的立场来看,您的建议是我应该将 Followers 关系从 Fiche 映射中取出,并将其替换为对存储库查询的调用。但是您作为示例提供的查询使用映射关系(在您的情况下称为 RelatedUsers);我尝试了查询,它抱怨该属性...
    • 它投诉了哪个属性?错误信息是什么?
    • 我更改了 Fiche 类和 Fiche 映射以删除 Followers 属性。当我尝试查询时,我收到以下错误:无法解析属性:追随者:DALAGScan.Fiche 我认为我在某些时候误解了你,因为一方面我知道我无法查询不是的属性映射,但另一方面,如果我映射它,我将不会从 Nhibernate 获得所需的行为......
    • 对,您可以(并且必须)将集合属性保留在映射上。我更多的是谈论将追随者重命名为相关用户,但您当然不需要这样做。对我来说,这更有意义,因为默认情况下,该集合将引用与 Fiche 相关的 all 用户对象。 “追随者”是相关用户对象的子集。另外,我同意詹姆斯的观点。您很可能希望为多个 Fiche 对象重用 User 对象,因此您需要多对多。
    • 我终于得到了属性重命名 :) 无论如何,如果我没看错,你提出的查询应该会重载 Nhibernate 生成的查询?如果这是正确的,我不知道“拔出”一些查询的能力......
    【解决方案2】:

    听起来您需要多对多而不是一对多。这样一个用户就可以被多个文件引用。

    至于您的集合的排序,AsList 将不起作用,除非您的表中有索引列;这是一个包含每条记录的数值的列,没有间隙。如果您不希望出现这种行为,则需要使用 order-by 属性。

    【讨论】:

    • 我终于试着按照你的方式去做了;我用不同的整数初始化了一个名为 UniqueIntId 的映射列,每个用户没有间隙。然后我更改了映射并告诉 AsList() 方法我想使用 UniqueIntId 作为索引。可惜没有运气,它坚持以同样的方式行事。网上有这个功能的例子吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 2012-10-10
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多