1

ISetの代わりに をプロジェクトに実装し始めたところIListです。それは、私が持っているコレクションをよりよく反映しているためです。

これにより、1 つのテーブルの作成で奇妙なエラーが発生しました。私が得ているエラーはです。

テーブル 'UserAddressAssignments' の null 許容列に PRIMARY KEY 制約を定義できません。

ユーザーとアドレスの間に多対多の関係があります。

public class User : BaseEntity
{
    public virtual System.Guid UserGuid { get; set; }
    public virtual string UserName { get; set; }
    public virtual Company Company { get; set; }
    public virtual Iesi.Collections.Generic.ISet<Address> UserAddressAssignments { get; set; }
}

ルックアップ列に対して生成している SQL が問題の原因であり、以下に示します。UserId問題を引き起こしている のは、列が null 可能であることです。

create table UserAddressAssignments (
    UserAddressAssignmentId INT not null,
   AddressId INT IDENTITY NOT NULL,
   UserId INT null,
   primary key (UserId, AddressId)
)

ここで奇妙なのは、会社と住所の間に同じ関係があり、うまく機能することです。

public class Company : BaseEntity
{
    public virtual System.Guid CompanyGuid { get; set; }
    public virtual string Name { get; set; }
    public virtual Iesi.Collections.Generic.ISet<Address> CompanyAddressAssignments { get; set; }
}

これにより、ルックアップ テーブルの正しい SQL が作成されます。

CREATE TABLE [dbo].[CompanyAddressAssignments](
    [CompanyId] [int] NOT NULL,
    [AddressId] [int] NOT NULL,
PRIMARY KEY CLUSTERED 
(
    [CompanyId] ASC,
    [AddressId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

キーの適切な非 null 属性を持つクラスター化されたキーを使用し、ユーザー ルックアップ列のように 3 番目の 'CompanyAddressAssignmentId' 列はありません。

Company と User の両方のマッピング オーバーライドも同じです。

public class CompanyMappingOverride : IAutoMappingOverride<Company>
{
        public void Override(FluentNHibernate.Automapping.AutoMapping<Company> mapping)
        {
            mapping.Map(x => x.Name);
            mapping.HasManyToMany(x => x.CompanyAddressAssignments).Table("CompanyAddressAssignments").Cascade.All();
        }
}

public class UserMappingOverride : IAutoMappingOverride<User>
{
    public void Override(FluentNHibernate.Automapping.AutoMapping<User> mapping)
    {
        mapping.References(x => x.Company).Cascade.All();
        mapping.HasManyToMany(x => x.UserAddressAssignments).Table("UserAddressAssignments").Cascade.All();
    }
}

クラスの構造とマッピングが同一であることがわかる限り、2つのルックアップテーブルがなぜそれほど異なって見えるのかについて、誰か提案はありますか?

IListこの問題を回避するために、ユーザー アドレスに を使用することにしました。

これにより、この create sql が発行されます。

CREATE TABLE [dbo].[CompanyAddressAssignments](
    [CompanyId] [int] NOT NULL,
    [AddressId] [int] NOT NULL,
PRIMARY KEY CLUSTERED 
(
    [CompanyId] ASC,
    [AddressId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

この不一致の原因について何か考えはありますか?

NHibernate のバージョンは 3.2.0.4000 です。

乾杯

スティーブ

4

1 に答える 1

0

右、私は問題が何であるかを発見しました。

私が取り組んでいるサイトには、NHibernate が追加されています。コード ファースト / スキーマ生成アプローチを使用するために、自動ツールを使用して既存のスキーマをクラスに変換し、そこから魔法のようにスキーマを作成しました。

NHhibernate デザイナーを使用してクラスを自動生成し、標準に合わせてエンティティをクリーンアップしました。

http://www.devart.com/entitydeveloper/nhibernate-designer.html

ツールがルックアップ テーブルのクラスを生成したときに、エラーが発生しました。したがって、UserAddressAssignment はシステム内に独自のクラスを持ちます。多対多の関係を作成する場合、これは通常必要ありません。ManyToMany テーブルの名前を指定して、マッピング オーバーライドで多対多のクラスと ALSO の両方を指定した NHibernate は、(当然のことながら) 混乱したに違いありません。

NHibernate Designer が処理しなければならなかったスキーマは、強制されていない関係の一部をきれいにするものではなかったことを指摘したいと思います。そのため、必要のないときにこのエンティティを作成したことを非難しているわけではありません。

したがって、以下に示す不要な UserAddressAssignment クラスを削除すると、すべてが期待どおりに機能しました。

  public class UserAddressAssignment : BaseEntity
    {
        public virtual int AddressId { get; set; }
        public virtual User User { get; set; }
        public virtual Address Address { get; set; }
    }

これが誰かに役立つことを願っています!

乾杯

スティーブ

于 2012-07-02T13:50:51.920 に答える