Я работаю с Fluent nHibernate в старой базе данных и имею таблицу основного пользователя и несколько таблиц расширений, содержащих дополнительную информацию о человеке. Эти таблицы расширения являются взаимно однозначными, что означает, что у человека будет только одна строка в таблице расширений, а таблица расширений должна всегда отображаться обратно одному человеку.Сопоставление таблицы расширений, которая может не иметь строки
Таблица: Человек
Колонны: PersonId, FirstName, LastName и т.д.
Стол: PersonLogin
Колонны: PersonID (FK, уникальный), имя пользователя, пароль и т.д.
У меня есть мои сопоставления, определенные этим (с несоответствующими свойствами опущены):
public PersonMap()
{
Table("Person");
Id(x => x.Id, "PersonID").Not.Nullable();
References(x => x.Login, "PersonID").LazyLoad();
}
public LoginMap()
{
Table("PersonLogin");
Id(x => x.Id, "PersonID").GeneratedBy.Foreign("Person");
References(x => x.Person, "PersonID").LazyLoad();
}
Это работает, когда у меня есть данные по обеим таблицам, но недавно я узнал, что некоторые из таблиц расширения не имеют данных для всех строк Person. Это заставило меня получить ошибки во время запроса. Таким образом, я добавил .NotFound.Ignore()
моим PersonMap делает его выглядеть следующим образом:
References(x => x.Login, "PersonID").LazyLoad().NotFound.Ignore();
Это заставило меня, чтобы получить ненужные выбирает из таблицы Вход из-за https://nhibernate.jira.com/browse/NH-1001, когда мой бизнес слой не нужно проецировать любой из таблицы расширения значения. Это приводит к тому, что производительность может быть ужасной в некоторых моих поисковых запросах.
Я просмотрел много сообщений, но не нашел солидного ответа о том, как решить этот сценарий. Ниже приведены параметры, которые я пробовал:
Вариант один:
Создание строк на столе расширения, чтобы гарантировать, что нет ни одного человека, без ряда на столе расширения, а затем удалите .NotFound.Ignore()
.
Проблема с этой опцией заключается в том, что она представляет собой устаревшую базу данных, и я не уверен, где мне нужно будет обновлять, чтобы обеспечить добавление PersonLogin при вставке Person.
Вариант второй:
Удалите ссылку PersonLogin из моего PersonMap и пользовательских загрузить его внутри моего класса Person. Как это:
public class Person
{
/// <summary> Gets or sets the PersonID </summary>
public virtual int Id { get; set; }
private bool loadedLogin;
private PersonLogin login;
public virtual PersonLogin Login
{
get
{
if (!loadedLogin)
{
login = SessionManager.Session().Get<PersonLogin>(Id);
loadedLogin = true;
}
return login;
}
set
{
login = value;
loadedLogin = true;
}
}
}
Проблема у меня с ним в том, что я не могу с готовностью принести данные при выполнении запроса, чтобы потянуть назад большое количество объектов Person и их логинов.
Вариант третий:
Я только начал играть, чтобы увидеть, если я мог бы написать обычай IEntityNotFoundDelegate не выбрасывать исключение для этих объектов.
private class CustomEntityNotFoundDelegate : IEntityNotFoundDelegate
{
public void HandleEntityNotFound(string entityName, object id)
{
if (entityName == "my.namespace.PersonLogin")
{
return;
}
else
{
throw new ObjectNotFoundException(id, entityName);
}
}
}
И я добавил это в конфиг
cfg.EntityNotFoundDelegate = new CustomEntityNotFoundDelegate();
Он ловит мой сценарий и возвращается назад, теперь вместо того, чтобы выбросить эту ошибку, но теперь, когда я пытаюсь спроецировать эти PersonLogin свойства на мой бизнес-объектов, он пытается использовать объект Proxy и выдает эту ошибку, которую я пытаюсь выяснить, могу ли я обрабатывать чисто (возможно, в IPostLoadEventListener).
System.Reflection.TargetException occurred
Message = Non-static method requires a target
Похоже, вы нашли решение сейчас. Мы стараемся хранить все в форме Q & A: 1 вопрос и 0 или много ответов. Я переработал некоторые из ваших «ответов», которые выглядят так, будто они действительно больше информации на вопрос, а не ответ, но последнее, по крайней мере, похоже, что часть его действительно является частью ответа. Было бы здорово, если бы вы могли отредактировать это, чтобы сохранить стиль Q & A немного лучше, чем мне удалось. – Flexo
Спасибо @Flexo. Я изначально написал все вместе, но решил опубликовать варианты в виде отдельных ответов, так как я думал, что это обеспечило лучшее обсуждение и позволило людям сбрасывать плохие варианты. Во всяком случае, я очистил сообщение и ответ и принял его. Спасибо! –