1

NHibernate は、一方向の関連付けを使用しているときに、外部キーと列で構成される一意のインデックスを持つことを妨げています。

//The classes
public class Method
{
    public virtual Guid ID { get; private set; }
    public virtual List<MethodParameter> Parameters { get; private set; }

    public Method()
    {
        this.Parameters = new List<MethodParameter>();
    }
}

public class MethodParameter
{
    public virtual Guid ID { get; private set; }
    public virtual string Name { get; private set; }

    protected MethodParameter() { }

    public MethodParameter(Method method, string name)
    {
        this.Name = name;
        method.Parameters.Add(this);
    }
}

//The mappings
public class MAP_Method : ClassMap<Method>
{
    public MAP_Method()
    {
        this.Table("[Method]");
        this.Id(x => x.ID).Access.BackingField().GeneratedBy.GuidComb();
        this.HasMany(x => x.Parameters)
            .Access.BackingField()
            .KeyColumn("[Method]")
            .Not.LazyLoad()
            .Cascade.AllDeleteOrphan();
    }
}

public class MAP_MethodParameter : ClassMap<MethodParameter>
{
    public MAP_MethodParameter()
    {
        this.Table("[MethodParameter]");
        this.Map(x => x.Name).Length(50).Not.Nullable();
    }
}

2 つの MethodParameters (名前: x と名前: y) を持つ単一の Method インスタンスを作成する場合、問題はありません。ただし、同じ MethodParameter 名を持つ同じトランザクションで 2 つの Method インスタンスを作成すると、一意のインデックス違反が発生します。

これは、[MethodParameter] ([Method] ASC、[Name] ASC) に一意のインデックスがあり、一方向の関連付けがあるためです。NHibernate は最初に [Method] 列に NULL を持つ子テーブルを挿入し、次に戻って更新します。 [メソッド] 値が正しい行。

(Method1, "x") (Method2, "x") の代わりに (null, "x") (null, "x") になるため、同一の MethodParameter 名を持つ 2 つの Method インスタンスを挿入する場合、これは明らかに問題です。

これが設計された動作であることは理解していますが、双方向の逆関連付けを行うか、DB から一意のインデックスを削除する必要があるようです。NULL を挿入してから更新するのではなく、挿入時に NHibernate に正しい [メソッド] ID を挿入させる方法はありますか?

4

1 に答える 1

1

アソシエーションは一方向であるため、次のオプションを設定する必要があります:inverse="false"アソシエーション ( <one-to-many>)、not-null="true"キー ( <key>)。パラメータの所有者を変更する予定がない場合はupdate="false"、キー ( <key>) を設定する必要があります。

FK列にnullを挿入することを防ぎます。

FluentNHibernate の例:

this.HasMany(x => x.Parameters)
    .Not.Inverse()     // 1
    .Not.KeyNullable() // 2
    .Not.KeyUpdate()   // 3
    .Access.BackingField()
    .KeyColumn("[Method]")
    .Not.LazyLoad()
    .Cascade.AllDeleteOrphan();

より良い説明については、次の回答をご覧ください https://stackoverflow.com/a/7601312/259946およびhttps://stackoverflow.com/a/11576097/259946

于 2012-08-03T17:33:26.307 に答える