FluentNHibernate One-To-One с использованием ограничения ForeignKey - PullRequest
0 голосов
/ 12 августа 2010

Хорошо, у меня есть 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();
    }
}

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

Если кто-нибудь знает, почему это может произойти, или альтернативный подход, пожалуйста, дайте мне знать.

Мне кажется действительно глупым, что это даже происходит?!

1 Ответ

2 голосов
/ 13 августа 2010

A one-to-one в NHibernate, по замыслу, является отношением, которое объединяет первичный ключ. Это неявные отношения, а не явные, в которых эти две сущности связаны только через подразумеваемое соглашение о том, что, если два ключа имеют одинаковое значение, они связаны. См .: NHibernate один к одному .

Судя по дизайну вашей базы данных, у вас на самом деле действует структура отношений один-ко-многим-многие-к-одному, а не один-к-одному. Ваша модель предметной области может выражать это как один-к-одному, но в основе это все еще один-ко-многим; в базе данных ваш OutboundEmail может иметь много OutboundEmailStatus, потому что ничто не останавливает несколько строк с одинаковым значением внешнего ключа.

Лично я бы перевернул его и поместил внешний ключ в OuboundEmail. Таким образом, ваша OutboundEmail будет иметь многозначное отношение к OutboundEmailStatus. ака. электронное письмо имеет один статус, но статус может быть связан с несколькими электронными письмами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...