FluentNHibernate — логический флаг, основанный на количестве из другой таблицы

#c# #fluent-nhibernate #formula #calculated-columns

#c# #fluent-nhibernate #формула #вычисляемые столбцы

Вопрос:

Я видел несколько подобных вопросов в SO, но я все еще не могу заставить это работать в моем коде, несмотря на то, что мой код выглядит как принятые ответы.

Во-первых, мое отображение (сокращенное)

 public SiteMap()
{
    Table("SiteDetail");

    Id(x => x.SiteId, "Id").GeneratedBy.Identity();
}
  

Затем структура другой таблицы

 CREATE TABLE [dbo].[EmailConfig](
    [SiteID] [int] NOT NULL,
    [Active] [int] NULL,
    [HeaderText] [int] NULL,
    [TrailerText] [int] NULL,
    [BodyText] [int] NULL,
    [CopyEmailTo] [varchar](255) NULL,
CONSTRAINT [PK_EmailConfig] PRIMARY KEY CLUSTERED ([SiteID] ASC)) 
  

И вот мое свойство в моем объекте

 public virtual bool EmailReceiptsEnabled { get; set; }
  

И вот сопоставление для установки этого свойства

 Map(x => x.EmailReceiptsEnabled)
    .Formula("(SELECT COUNT(e.SiteId) FROM EmailConfig e WHERE e.SiteId = SiteId AND e.Active = 1)");
  

Когда я комментирую это сопоставление свойств, все работает нормально. Когда я оставляю его включенным, мой репозиторий возвращает null при попытке выбрать один сайт. Ошибка не выдается, кроме исключения с нулевой ссылкой на странице, пытающейся получить доступ к свойству объекта site.

Редактировать:

Я изменил свое решение, чтобы вернуть объект следующим образом:

 public class EmailConfiguration : CoreObjectBase
{
    public virtual int SiteId { get; set; }
    public virtual int Active { get; set; }
}
  

Со свойством в моем Site классе

 public virtual EmailConfiguration EmailConfiguration { get; set; }
  

И сопоставление для объекта

 public class EmailConfigurationMap : ClassMap<EmailConfiguration>
{
    public EmailConfigurationMap()
    {
        Table("EmailConfig");

        Id(x => x.SiteId);

        Map(x => x.Active);
    }
}
  

И затем отображение на моем сайте

 References(x => x.EmailConfiguration, "Id");
  

И это выдает ошибку

NHibernate.Исключение ObjectNotFoundException: не существует строки с заданным идентификатором

Проблема в том, что EmailConfig не содержит записи, пока клиент не зайдет в приложение для настройки своей электронной почты. Это нельзя изменить, но мне нужно, чтобы мое приложение могло использовать эти данные. Есть идеи о том, как отобразить эту вещь?

Еще одна правка

Я смог заставить его работать, изменив свойство на это

 public virtual IList<EmailConfiguration> EmailConfigurations { get; set; }
  

И затем реализация этой полной катастрофы

 HasMany<EmailConfiguration>(x => x.EmailConfigurations)
    .KeyColumn("SiteId")
    .Inverse();
  

Я думаю, что пойду тихо поплачу, пока не смогу понять, как заставить этот беспорядок работать правильно. Поскольку EmailConfig таблица использует PK таблицы моего сайта в качестве своего первичного ключа, единственные возможности — иметь 1 запись или вообще не иметь записей. References сбой при null с серьезной ошибкой. hasOne также не работает (заставляет программу вообще не извлекать мои Site объекты без каких-либо ошибок).

Комментарии:

1. Перед редактированием, как вы запрашивали объект вашего сайта. Это было не в SiteID? Вы посмотрели на запрос, который он выполнял, когда вы отображали формулу через файлы журнала или NHProf? Я настроил сценарий, подобный этому, и я выполнял запрос по примеру, и эта формула испортила запрос для меня. Также я думаю, что это действительно взаимно однозначное отношение, поскольку обе таблицы имеют один и тот же первичный ключ.

2. На сайте есть аббревиатура из 4 символов, которую я использовал для поиска на сайте. Я использую класс для определения выражения linq, которое затем передается в мой репозиторий, который использует выражение с linq для nhibernate. Важно то, что запрос работает без сопоставления, но ничего не возвращает, когда сопоставление включено.

3. Вы действительно смотрели на запрос, который попадает в базу данных, хотя, когда у вас есть сопоставленная формула, по сравнению с тем, когда у вас ее нет сопоставленной? Я не думаю, что ваша формула — это то, что обязательно вызывает ваши проблемы. Похоже, что предложение where генерируется по-другому, когда у вас это сопоставлено, потому что вы получаете обратно нулевой объект. Если бы это было неправильное отображение, похоже, что значение этого свойства было бы единственным, что было неправильным.