NHibernate Formula - 实体的映射列表

NHibernate Formula - Mapping list of entities

我想在 Fluent NHibernate 中创建一个公式,它有一个获取结果列表的子查询。

我有一个名为 node_cable 的 table,其中包含以下列: |id|节点|电缆|

节点列描述了一个节点,而电缆描述了这些节点之间的连接。

示例:

|id|node|cable|

|1|2000|100|

|2|2001|100|

这意味着电缆 100 连接节点 2000 和 2001。

下面的查询给了我想要的结果:

SELECT * 
FROM node_cable as AA
WHERE AA.node != 3565
AND AA.cable IN
(
    SELECT * FROM
    (
        SELECT BB.cable
        FROM node_cable as BB
        WHERE BB.node = 3565
    ) AS subquery
)

我如何在 Fluent NHibernate 中编写它?我试过使用 Map.Formula,但没有成功:

Map(x => x.siblings).Formula(@"SELECT AA.node
                        FROM node_cable as AA
                        WHERE AA.node != 3565
                        AND AA.cable IN
                        (
                            SELECT * FROM
                            (
                                SELECT BB.cable
                                FROM node_cable as BB
                                WHERE BB.node = 3565
                            ) AS subquery
                        )");

兄弟 属性 定义为:

public virtual IList<NodeEntity> siblings { get; set; }

我得到的错误是:

{"Could not determine type for: System.Collections.Generic.IList`1[[GOTHAM.Model.NodeEntity, GOTHAM-MODEL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, for columns: NHibernate.Mapping.Formula( SELECT AA.node\r\n FROM node_cable as AA\r\n WHERE AA.node != 3565\r\n AND AA.cable IN\r\n (\r\n SELECT * FROM\r\n (\r\n SELECT BB.cable\r\n FROM node_cable as BB\r\n WHERE BB.node = 3565\r\n ) AS subquery\r\n ) )"}

有人知道吗?

编辑: 查询结果图片: http://gyazo.com/0d3152314631500ece81e6c0b2efe3d5

谢谢!

编辑:

现在我有以下映射到兄弟姐妹:

      HasMany(x => x.siblings)
    .Not.LazyLoad() 
    .AsBag()
    .Fetch.Join()
    .Inverse()
    .Table("node_cable")
    .KeyColumn("id")
    .Subselect(
    @"SELECT
    id AS P1,
    node AS P2,
    cable AS P3 
    FROM node_cable as AA
    WHERE AA.node != 3565
    AND AA.cable IN
    (
        SELECT * FROM
        (
            SELECT BB.cable
            FROM node_cable as BB
            WHERE BB.node = 3565
        ) AS subquery
    )"
  );

然而,这只会 return 我所在的同一节点。我也可以只删除给出相同结果的子查询。

我做错了什么?

查看此概述(文档的后半部分)如何进行集合映射:

Mapping-by-Code - Set and Bag

我想说,有一些误解。

首先,.Formula()是对标准.Column()的替代。背后的想法是,我们可以计算一些值(比率 * 数量)......它不能用于集合映射。这里正好是return列

其次我们尝试映射集合:

public virtual IList<NodeEntity> siblings { get; set; }

虽然映射 .Map() 仅适用于 值类型 。所以我们需要不同的映射 .HasMany() 甚至 .HasManyToMany() 如果它们是一对 table

// this way we mapp collections
HasMany(x => x.siblings)
   ...

而且,我不确定内部 select,子查询。通常我们映射实体然后对于HasMany,table由实体映射定义。

如果关系是一对多的,我们需要我们的集合项 NodeEntity 被映射 "standard way" - 用作参考。

如果我们需要一个特殊的select...我们可以使用不同的方法:

7.2. Collections of dependent objects

<set name="SomeNames" table="some_names" lazy="true">
    <key column="id"/>
    <composite-element class="Eg.Name, Eg"> <!-- class attribute required -->
        <property name="Initial"/>
        <property name="First"/>
        <property name="Last"/>
    </composite-element>
</set>

在这种情况下,我们通过 属性 将元素(例如 NodeEntity)属性 映射到某些 select,在上面的示例中 table="some_names" .但 NHibernate 更进一步...

我们可以用内联 select 替换 table(我们回到问题中提到的公式)

威武设置为:<subselect>

<set name="siblings" lazy="true">

    <subselect>
    SELECT AA.node
    property1 AS P1,
    property2 AS P2,
    property3 AS P3,
    FROM node_cable as AA
    WHERE AA.node != 3565
    AND AA.cable IN
    (
        SELECT * FROM
        (
            SELECT BB.cable
            FROM node_cable as BB
            WHERE BB.node = 3565
        ) AS subquery
    )
    </subselect>

    <key column="node"/>
    <composite-element class="NodeEntity">
        ...
    </composite-element>
</set>

太棒了,所有的都可以转换成流利的:

HasMany(x => x.siblings)
    .Subselect(....