3

NHibernateに、この1対1の関係でテーブル列のAccountCode列をマップさせることができません(それぞれに単一があり、それぞれに単一があります)。BeneficiaryAccountCodeAccountBeneficiaryBeneficiaryAccount

クラス:

public class Account
{
    ...
    public virtual string Name { get; protected set; }
    public virtual string Code { get; protected set; }
}

public class Beneficiary
{
    ...
    public virtual int Id { get; set; }
    public virtual string Name { get; protected set; }
    public virtual Account Account { get; protected set; }
    public virtual BeneficiaryGroup Group { get; protected set; }
}

SQL:

CREATE VIEW dbo.Account AS
    SELECT DISTINCT RTRIM(LTRIM(ACCNT_NAME)) AS Name, 
                    RTRIM(LTRIM(ACCNT_CODE)) AS Code
    FROM myremoteserver.schema.tablename
    WHERE ACCNT_TYPE NOT IN ('B', 'P')


CREATE TABLE dbo.Beneficiary
(
    Id INT IDENTITY(1,1) NOT NULL, 
    BeneficiaryGroupId INT NOT NULL CONSTRAINT FK_Beneficiaries_BeneficiaryGroup FOREIGN KEY REFERENCES dbo.BeneficiaryGroup (Id), 
    Name VARCHAR(100) NOT NULL,
    AccountCode VARCHAR(100) NOT NULL,
    CONSTRAINT PK_Beneficiary PRIMARY KEY (Id)
)

さまざまなバリアントを使用しようとするHasManyと、NHibernateはBeneficiary.Id列に参加しようとします。

、、(結合がすでに存在することを示します)と(関係が実際に1対1であるため、失敗しますMap)のさまざまなバリエーションを試しました。ReferencesJoinHasMany

NHibernateにこれら2つのクラスをそれらの列に正しくマップさせるにはどうすればよいですか?


さまざまな流暢なマッピングを試してみると、私のIAutoMappingOverride<Beneficiary>場合、次のことが起こります。

mapping.HasOne(b => b.Account);
mapping.HasOne(b => b.Account).PropertyRef(sa => sa.Code);
mapping.HasOne(b => b.Account).PropertyRef(sa => sa.Code).ForeignKey("none");

生成されたSQLは、のBeneficiary.Id代わりにフィールドを使用しますBeneficiary.AccountCode。(質問する前に、ビューであるため「none」を使用しAccountています。キーを持つことはできません)。

mapping.Join("AccountCode", x => x.References(y => y.Account));
mapping.Join("Account", b => b.KeyColumn("AccountCode"));

結果はTried to add join to table 'Account' when already added.

と:

mapping.Map(b => b.Account, "AccountCode");
mapping.Map(b => b.Account).ReadOnly().Column("AccountCode");

結果:

次のタイプを判別できませんでした:.Account 、、 Version = 1.0.0.0、Culture = neutral、PublicKeyToken = null、列の場合:NHibernate.Mapping.Column(AccountCode)

mapping.References(b => b.Account).Column("Code");

結果はInvalid column name 'Code'.

と:

mapping.References(b => b.Account).Column("AccountCode");
mapping.References(b => b.Account).Column("AccountCode").Access.Property();

すべてのオーバーライドをオーバーライドします(キー列IReferenceConventionを持つようにいくつかのクラスをマッピングします)。<class name>Code

しようとするとHasMany

mapping.HasMany<Account>(b => b.Account).KeyColumn("AccountCode");

カスタムタイプはUserCollectionTypeを実装していません:.Account

4

2 に答える 2

7
// in BeneficiaryMapping
mapping.References(b => b.Account)
    .Column("AccountCode" /* of Beneficiary table*/)
    .PropertyRef(a => a.Code); // use the Column of Code as the joincolumn in Account table
于 2012-10-22T12:19:36.917 に答える
2

このアプローチはFiroのアプローチに似ていますが、より単純なマッピングです。ReferencesNHでは、エンティティの主キープロパティ以外のプロパティを選択して別のタイプを参照できるため、彼が提案するように使用します。PropertyRefNHは、値をビューAccountCodeの「キー」として使用することを「認識」しているため、これは必要ありません。Account

マップする方法は次のAccountとおりです。

public class AccountMap : ClassMap<Account>
{
    public AccountMap()
    {
        // Code as a psuedo primary key in the view:
        Id(acc => acc.Code)
            .GeneratedBy.Assigned();

        Map(acc => acc.Name);

        // Add other mappings here...

        // Ensure NH doesn't try to update the lookup view:
        ReadOnly();
    }
}

外観は次のようBeneficiaryにマッピングされます。

public class BeneficiaryMap : ClassMap<Beneficiary>
{
    public BeneficiaryMap()
    {
        Id(b => b.Id)
            .GeneratedBy.Identity()
            .UnsavedValue(0);

        Map(b => b.Name);
        // Other mapped properties...

        References<BeneficiaryGroup>(b => b.Group, "BeneficiaryGroupId");
        References<Account>(b => b.Account, "AccountCode");
    }
}
于 2012-10-22T15:52:54.223 に答える