在NHibernate映射文件中加入由第三个条件限制的两个表

时间:2012-06-11 09:01:55

标签: nhibernate nhibernate-mapping

我有以下表格:

foo {
    id;
    catColorId;
}

bar {
    fooId;
    catTypeId;
    barName;
}

cat {
     catColorId;
     catTypeId;
     priority;
}

bar表格有复合身份fooId, catTypeId
cat表具有复合ID catColorId, catTypeId

我想把它们映射到:

class Foo {
    int Id;
    IList<Bar> BarList { get; set; }
}

BarList应由cat.priority

订购

有关如何在.hbm.xml中映射此内容的任何想法?

更新:

如果我可以获得映射,那么在填写Foo.BarList时会生成查询(或其中的一些变体),这将是完美的:

select 
    b.fooId, 
    b.catTypeId,
    b.barName,
from
    join foo as f 
    join bar as b on f.id = b.fooId
    join cat as c on f.catColorId = c.catColorId and b.catTypeId = c.catTypeId
where
    f.id = @fooId
order by 
    c.priority

我最后一次加入有困难:b.catTypeId = c.catTypeId
你如何在hbm标记中定义这样的限制?

1 个答案:

答案 0 :(得分:1)

目前的示例严格来说是Many-To-Many映射。

public class Foo {
    public virtual int Id { get; set; }
    public virtual IList<Cat> Cats { get; set; }
}

// there is no Bar entity in this example; it is a cross-reference table used by nhibernate, but there is no entity in your domain

public class Cat {
    public virtual int Id { get; set; }
    public virtual IList<Foo> Foos { get; set; }
}

映射:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="Models"
    namespace="Models">
    <class name="Foo" table="foo">
        <id name="Id" column="Id">
            <generator class="identity" />
        </id>
        <bag name="Cats" table="bar">
            <key column="FooId"></key>
            <many-to-many column="CatId" class="Cat" />
        </bag>
    </class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="Models"
    namespace="Models">
    <class name="Cat" table="cat">
        <id name="Id" column="Id">
            <generator class="identity" />
        </id>
        <bag name="Foo" table="bar">
            <key column="CatId"></key>
            <many-to-many column="FooId" class="Foos" />
        </bag>
    </class>
</hibernate-mapping>

但是,如果Foos和Cats之间的关系比关系更有意义(比如,你需要向Bar添加其他属性),你可以这样做:

public class Foo {
    public virtual int Id { get; set; }
    public virtual IList<Bar> Bars { get; set; }
}

public class Bar
{
    public virtual Foo Foo { get; set; }
    public virtual Cat Cat { get; set; }
}

public class Cat {
    public virtual int Id { get; set; }
    public virtual IList<Bar> Bars { get; set; }
}
// you can get all Cats for a Foo via Foo.Bars and vice versa

映射:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="Models"
    namespace="Models">
    <class name="Foo" table="foo">
        <id name="Id" column="Id">
            <generator class="identity" />
        </id>
        <bag name="Bars" inverse="true">
            <key column="CatId"></key>
            <one-to-many class="Bar"/>
        </bag>
    </class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="Models"
    namespace="Models">
    <class name="Cat" table="cat">
        <id name="Id" column="Id">
            <generator class="identity" />
        </id>
        <bag name="Bars" inverse="true">
            <key column="FooId"></key>
            <one-to-many class="Bar"/>
        </bag>
    </class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="Models"
    namespace="Models">
    <class name="Bar" table="bar">
        <composite-id>
          <key-many-to-one class="Foo" name="Foo" column="FooId" />
          <key-many-to-one class="Cat" name="Cat" column="CatId" />
        </composite-id>
    </class>
</hibernate-mapping>

很抱歉,如果我的HBM标记生锈了;我习惯按代码进行映射。