映射以查看自定义字段名称 - 一对一关系

时间:2012-10-19 13:49:07

标签: view fluent-nhibernate sql-server-2000

我无法让NHibernate在这种一对一关系中映射AccountCodeBeneficiary列的AccountCode列(每个Account都有一个Beneficiary,每个Beneficiary都有一个Account)。

类:

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列。

我尝试了MapReferencesJoin的不同变体(告诉我连接已经存在)和HasMany(失败,因为关系是确实是一对一的。

如何让NHibernate将这两个类正确地映射到它们的列?


在尝试不同的流畅映射时,在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。 (在你问之前,我使用“无”,因为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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

这种方法类似于Firo,但是在更简单的映射中。它像他建议的那样使用References,因为NH允许你选择除实体主键属性之外的属性来引用另一种类型。 PropertyRef不是必需的,因为NH“知道”它将使用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");
    }
}