使用外键约束的 FluentNHibernate 一对一
好的,我有 2 个对象和一个外键。
第一个对象是。
public class OutboundEmailMap : ClassMap<OutboundEmail>
{
public OutboundEmailMap()
{
Table("OutboundEmail");
Id(x => x.Id, "OutboundEmailId")
.UnsavedValue(0)
.GeneratedBy.Identity();
Map(x => x.OutboundEmailGuid);
Map(x => x.FromAccountName);
Map(x => x.ToAccountName);
Map(x => x.FromContactFirstName);
Map(x => x.FromContactLastName);
Map(x => x.ToContactFirstName);
Map(x => x.ToContactLastName);
Map(x => x.FromEmailAddress);
Map(x => x.ToEmailAddress);
Map(x => x.EmailTemplateID);
Map(x => x.SentDate);
Map(x => x.Subject);
Map(x => x.XMLTokenDictionary);
Map(x => x.IsFax);
Map(x => x.TransmittalId);
//References<Transmittal>(x => x.Transmittal)
// .Column("TransmittalID")
// .LazyLoad()
// .Cascade.None();
HasOne<OutboundEmailStatus>(x => x.Status)
.ForeignKey("FK_OutboundEmailStatus_OutboundEmail")
.Cascade.None();
}
}
第二类是
public class OutboundEmailStatusMap : ClassMap<OutboundEmailStatus>
{
public OutboundEmailStatusMap()
{
Table("OutboundEmailStatus");
Id(x => x.Id, "OutboundEmailStatusID")
.UnsavedValue(0)
.GeneratedBy.Identity();
References(x => x.OutboundEmail, "OutboundemailID");
Map(x => x.EmailStatus, "EmailStatusID");
Map(x => x.EmailStatusDate);
}
}
外键是
USE [Mail]
GO
ALTER TABLE [dbo].[OutboundEmailStatus] WITH CHECK ADD CONSTRAINT [FK_OutboundEmailStatus_OutboundEmail] FOREIGN KEY([OutboundEmailID])
REFERENCES [dbo].[OutboundEmail] ([OutboundEmailID])
GO
ALTER TABLE [dbo].[OutboundEmailStatus] CHECK CONSTRAINT [FK_OutboundEmailStatus_OutboundEmail]
GO
最后这是生成的查询
SELECT top 20 this_.OutboundEmailId as Outbound1_1_1_,
this_.OutboundEmailGuid as Outbound2_1_1_,
this_.FromAccountName as FromAcco3_1_1_,
this_.ToAccountName as ToAccoun4_1_1_,
this_.FromContactFirstName as FromCont5_1_1_,
this_.FromContactLastName as FromCont6_1_1_,
this_.ToContactFirstName as ToContac7_1_1_,
this_.ToContactLastName as ToContac8_1_1_,
this_.FromEmailAddress as FromEmai9_1_1_,
this_.ToEmailAddress as ToEmail10_1_1_,
this_.EmailTemplateID as EmailTe11_1_1_,
this_.SentDate as SentDate1_1_,
this_.Subject as Subject1_1_,
this_.XMLTokenDictionary as XMLToke14_1_1_,
this_.IsFax as IsFax1_1_,
this_.TransmittalId as Transmi16_1_1_,
outboundem2_.OutboundEmailStatusID as Outbound1_7_0_,
outboundem2_.EmailStatusID as EmailSta2_7_0_,
outboundem2_.EmailStatusDate as EmailSta3_7_0_,
outboundem2_.OutboundemailID as Outbound4_7_0_
FROM OutboundEmail this_
left outer join OutboundEmailStatus outboundem2_
on this_.OutboundEmailId = outboundem2_.OutboundEmailStatusID
WHERE this_.TransmittalId = '7789322e-acd6-4cb8-9c43-5bdaec52aa8a' /* @p0 */
ORDER BY this_.ToAccountName asc
所以问题如您所见,无论出于何种原因,它生成的查询都会尝试使用外键,尽管将外键连接到 OutboundEmailStatusID 而不是 OutboundEmailID
如果有人知道为什么会发生这种情况,或者有替代方法,请告诉我。
对我来说这真的很愚蠢,甚至发生这种事?!
Ok I have 2 objects and a foreign key.
The first object is.
public class OutboundEmailMap : ClassMap<OutboundEmail>
{
public OutboundEmailMap()
{
Table("OutboundEmail");
Id(x => x.Id, "OutboundEmailId")
.UnsavedValue(0)
.GeneratedBy.Identity();
Map(x => x.OutboundEmailGuid);
Map(x => x.FromAccountName);
Map(x => x.ToAccountName);
Map(x => x.FromContactFirstName);
Map(x => x.FromContactLastName);
Map(x => x.ToContactFirstName);
Map(x => x.ToContactLastName);
Map(x => x.FromEmailAddress);
Map(x => x.ToEmailAddress);
Map(x => x.EmailTemplateID);
Map(x => x.SentDate);
Map(x => x.Subject);
Map(x => x.XMLTokenDictionary);
Map(x => x.IsFax);
Map(x => x.TransmittalId);
//References<Transmittal>(x => x.Transmittal)
// .Column("TransmittalID")
// .LazyLoad()
// .Cascade.None();
HasOne<OutboundEmailStatus>(x => x.Status)
.ForeignKey("FK_OutboundEmailStatus_OutboundEmail")
.Cascade.None();
}
}
The 2nd Class is
public class OutboundEmailStatusMap : ClassMap<OutboundEmailStatus>
{
public OutboundEmailStatusMap()
{
Table("OutboundEmailStatus");
Id(x => x.Id, "OutboundEmailStatusID")
.UnsavedValue(0)
.GeneratedBy.Identity();
References(x => x.OutboundEmail, "OutboundemailID");
Map(x => x.EmailStatus, "EmailStatusID");
Map(x => x.EmailStatusDate);
}
}
And the Foreign Key is
USE [Mail]
GO
ALTER TABLE [dbo].[OutboundEmailStatus] WITH CHECK ADD CONSTRAINT [FK_OutboundEmailStatus_OutboundEmail] FOREIGN KEY([OutboundEmailID])
REFERENCES [dbo].[OutboundEmail] ([OutboundEmailID])
GO
ALTER TABLE [dbo].[OutboundEmailStatus] CHECK CONSTRAINT [FK_OutboundEmailStatus_OutboundEmail]
GO
And Lastly this is the query that is generated
SELECT top 20 this_.OutboundEmailId as Outbound1_1_1_,
this_.OutboundEmailGuid as Outbound2_1_1_,
this_.FromAccountName as FromAcco3_1_1_,
this_.ToAccountName as ToAccoun4_1_1_,
this_.FromContactFirstName as FromCont5_1_1_,
this_.FromContactLastName as FromCont6_1_1_,
this_.ToContactFirstName as ToContac7_1_1_,
this_.ToContactLastName as ToContac8_1_1_,
this_.FromEmailAddress as FromEmai9_1_1_,
this_.ToEmailAddress as ToEmail10_1_1_,
this_.EmailTemplateID as EmailTe11_1_1_,
this_.SentDate as SentDate1_1_,
this_.Subject as Subject1_1_,
this_.XMLTokenDictionary as XMLToke14_1_1_,
this_.IsFax as IsFax1_1_,
this_.TransmittalId as Transmi16_1_1_,
outboundem2_.OutboundEmailStatusID as Outbound1_7_0_,
outboundem2_.EmailStatusID as EmailSta2_7_0_,
outboundem2_.EmailStatusDate as EmailSta3_7_0_,
outboundem2_.OutboundemailID as Outbound4_7_0_
FROM OutboundEmail this_
left outer join OutboundEmailStatus outboundem2_
on this_.OutboundEmailId = outboundem2_.OutboundEmailStatusID
WHERE this_.TransmittalId = '7789322e-acd6-4cb8-9c43-5bdaec52aa8a' /* @p0 */
ORDER BY this_.ToAccountName asc
So the issue is as you see, for whatever reason the query it generates tries to use the foreign key, though connecting the foreign key to OutboundEmailStatusID instead of OutboundEmailID
If anyone knows why this might happen, or an alternative approach, please let me know.
It seems really silly to me that this even happens?!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据设计,NHibernate 中的一对一是通过主键连接的关系。这是一种隐式关系,而不是显式关系,因为两个实体仅通过隐式约定关联,即如果两个键具有相同的值,则它们会关联。请参阅: NHibernate 一对一。
从你的数据库设计来看,你实际上有一个一对多-多对一的关系结构,而不是一对一的关系结构。您的领域模型可能将其表示为一对一,但底层它仍然是一对多;在数据库中,您的 OutboundEmail 可以有许多 OutboundEmailStatus,因为没有什么可以阻止多行具有相同的外键值。
就我个人而言,我会翻转它并将外键放在 OuboundEmail 上。这样,您的 OutboundEmail 将具有与 OutboundEmailStatus 的多对一关系。又名。一封电子邮件具有单一状态,但一个状态可以与多封电子邮件关联。
A
one-to-one
in NHibernate is, by design, a relationship that joins over the primary key. It's an implicit relationship, rather than explicit, in that the two entities are related only through an implied convention that if the two keys have the same value they're associated. See: NHibernate one-to-one.Judging by your database design, you actually have a one-to-many - many-to-one relationship structure going on, not a one-to-one. Your domain model may express it as a one-to-one, but underlying it's still a one-to-many; in the database your OutboundEmail can have many OutboundEmailStatus's because there's nothing stopping multiple rows having the same foreign-key value.
Personally, I'd flip it around and put the foreign-key on the OuboundEmail. That way your OutboundEmail would have a many-to-one to OutboundEmailStatus. aka. an email has a single status, but a status could be associated with multiple emails.