2010-08-12 60 views
0

好吧我有2個對象和一個外鍵。使用ForeignKey約束的FluentNHibernate一對一

第一個對象是。

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(); 
    } 
} 

第2類是

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

如果有人知道爲什麼會出現這種情況,或者有其他方法,請告訴我。

這似乎真的很愚蠢,甚至發生?!

回答

2

NHibernate中的one-to-one在設計上是一種通過主鍵連接的關係。這是一種隱含的關係,而不是顯式的,因爲這兩個實體只通過隱含約定相關,如果兩個鍵具有相同的值,則它們相關聯。參見:NHibernate one-to-one

從你的數據庫設計來判斷,你實際上有一對一 - 多對一的關係結構,而不是一對一的關係結構。您的域模型可能會將其表示爲一對一,但其基礎仍然是一對多;在數據庫中,你的OutboundEmail可以有很多OutboundEmailStatus,因爲沒有什麼能阻止具有相同外鍵值的多行。

個人而言,我會翻轉它並將外鍵放在OuboundEmail上。這樣你的OutboundEmail就會有多對一的OutboundEmailStatus。又名。電子郵件具有單一狀態,但狀態可能與多個電子郵件相關聯。

+0

是的,我們正在討論把密鑰放在OutboundEmail表上。非常感謝您的意見,這很有道理。 – MattB 2010-08-13 11:24:20

+0

而我想我沒有足夠的聲望來投票給你:( – MattB 2010-08-13 11:24:51