NHibernate具有附加约束的一对一关系

时间:2020-07-21 14:29:53

标签: nhibernate nhibernate-xml-mapping

我有两个相互连接的表,每个路由最多可以有一个可选的来源,最多有一个可选的目的地。

ER schema

CREATE TABLE [Dbo].[tblRoute]
(
  RouteId BIGINT NOT NULL
 ,Payload NVARCHAR(100) NOT NULL
 ,CONSTRAINT PK_Route
    PRIMARY KEY ( RouteId )
)

CREATE TABLE [Dbo].[tblRouteEnd]
(
  RouteId BIGINT NOT NULL
 ,IsOrigin BIT NOT NULL
 ,Location NVARCHAR(100) NOT NULL
 ,CONSTRAINT PK_RouteEnd
    PRIMARY KEY ( RouteId, IsOrigin )
 ,CONSTRAINT FK_RouteEnd_Route
    FOREIGN KEY ( RouteId )
      REFERENCES [Dbo].[tblRoute] ( RouteId )
      ON UPDATE CASCADE
      ON DELETE CASCADE
)

现在我需要将其映射到NHibernate实体类。

public class Route
{
  public virtual long RouteId { get; set; }
  public virtual string Payload { get; set; }
  public virtual RouteEnd Origin { get; set; }       // Optional, should remain null if there is no origin
  public virtual RouteEnd Destination { get; set; }  // Optional, should remain null if there is no destination
}

public class RouteEnd
{
  public virtual long RouteId { get; set; }
  public virtual string Location { get; set; }
  public virtual Route MasterRoute { get; set; } // Mandatory, must always point to the owning route
}

我希望在一对一关系的帮助下进行映射,但是我不知道如何制作NHibernate,在寻找Route的起源时,请仅考虑那些RouteEnd IsOrigin等于true的记录。

对称地,当寻找Route目的地时,它只需要考虑RouteEnd等于false的那些IsOrigin记录。

在两种情况下,合格的RouteEnd都不超过一个。因此,形式上是一对一的,但是如何在XML映射中实现呢?

1 个答案:

答案 0 :(得分:0)

要一对一使用,在两个类中都需要相同的id字段。在您的情况下,RouteEnd应该具有一个复合ID类,以反映db中的PK。

此处最合适的做法是创建从Route到RouteEnd的一对多。您可以在映射中为Route中的RouteEnd-collection添加一个where子句:

where="IsOrigin = 1"

...或通过使用例如获取第一个RouteEnd实例LINQ。

public class Route
{
    public virtual long RouteId { get; set; }
    public virtual string Payload { get; set; }

    protected internal virtual ISet<RouteEnd> RouteEndsHbm { get; set; } = new HashSet<RouteEnd>();

    public virtual RouteEnd Origin => RouteEndsHbm.FirstOrDefault(route => route.IsOrigin);
}