我无法让NHibernate在这种一对一关系中映射AccountCode
表Beneficiary
列的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
列。
我尝试了Map
,References
,Join
的不同变体(告诉我连接已经存在)和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
答案 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");
}
}