中间的 Nhibernate ComposedId table

Nhibernate ComposedId on intermediate table

我想要一个只有两个外键(作为 ComposedId)的中间 table。 但是 NHibernate 会自动创建一个 "id" 属性.

我有以下类

public class Lace
{
    public virtual int Id { get; set; }
    public virtual string Hostname { get; set; }

    public virtual IList<LaceHasCard> LaceHasCards { get; set; }
}

public class Card
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }

    public virtual IList<LaceHasCard> LaceHasCards { get; set; }
}

和这个手动创建的中间体table

public class LaceHasCard
{
    public virtual Card Card { get; set; }
    public virtual Lace Lace { get; set; }
}

映射

public LaceMapping()
{
    Id(x => x.Id, map => map.Generator(Generators.Native));
    Property(x => x.Hostname);

    Bag(x => x.LaceHasCards, col =>
    {
        col.Key(k => k.Column("LaceId"));
        col.Inverse(true);
    }, r => r.OneToMany());
}

public CardMapping()
{
    Id(x => x.Id, map => map.Generator(Generators.Native));
    Property(x => x.Name);

    Bag(x => x.LaceHasCards, col =>
    {
        col.Key(k => k.Column("CardId"));
        col.Inverse(true);
    }, r => r.OneToMany());
}

中级table映射

public LaceHasCardMapping()
{
    //ComposedId(map =>
    //{
    //    map.Property(x => x.Card.Id, a =>
    //    {
    //        a.Column("CardId");
    //    });
    //    map.Property(x => x.Lace.Id, a =>
    //    {
    //        a.Column("LaceId");
    //    });
    //});

    ManyToOne(x => x.Card, map =>
    {
        map.Column("CardId");
    });

    ManyToOne(x => x.Lace, map =>
    {
        map.Column("LaceId");
    });
}

如果我在 ComposedId 注释掉的情况下创建架构,NHibernate 将在 table.

中创建一个 "id" 属性
CREATE TABLE [dbo].[LaceHasCard] (
    [id]     INT NOT NULL,
    [CardId] INT NULL,
    [LaceId] INT NULL,
    PRIMARY KEY CLUSTERED ([id] ASC),
    CONSTRAINT [FKDC6D54711CD160AE] FOREIGN KEY ([CardId]) REFERENCES [dbo].[Card] ([Id]),
    CONSTRAINT [FKDC6D547151F8AF85] FOREIGN KEY ([LaceId]) REFERENCES [dbo].[Lace] ([Id])
);

如果我尝试使用 ComposedId 创建架构,我会收到以下错误消息:

Unable to instantiate mapping class (see InnerException): EmpLaceMgmt.Models.Mappings.LaceHasCardMapping

告诉 NHibernate 创建组合 Id 的正确方法是什么?

我给你个建议,只是我的观点——不要使用复合id。在数据库中使用标准主键及其 C#/实体表示形式 Id { get; set; }

Chapter 24. Best Practices

...

Declare identifier properties on persistent classes.

NHibernate makes identifier properties optional. There are all sorts of reasons why you should use them. We recommend that identifiers be 'synthetic' (generated, with no business meaning) and of a non-primitive type. For maximum flexibility, use Int64 or String.

另请参阅维基上有关 synthetic, surrogate keys 的更多信息。

根据我的经验,我们不应该担心有这样的配对对象:

public class LaceHasCard
{
    public virtual int Id { get; set; } // the key
    public virtual Card Card { get; set; }
    public virtual Lace Lace { get; set; }
}

因为以后访问起来会很方便:

session.Get<LaceHasCard>(id)

也可以在 Subqueries 中使用它(用于过滤带花边的卡片,反之亦然)

数据库中的一列是自动生成的,应该不会产生任何额外的不良影响。但是处理这样的 table 有点(很多)容易......

所以,总结一下,我的建议是,让所有实体成为一级公民,拥有全部权利(包括 synthetic/surrogate 密钥)