NHibernate - у меня их много, но я хочу только одного! - PullRequest
0 голосов
/ 09 апреля 2010

У меня есть пользователь, у которого может быть много писем. Это отображается через коллекцию списков (предоставляемую IEnumerable Emails на пользователя). Для каждого пользователя один из электронных писем будет основным (свойство Boolean IsPrimary в электронной почте).

Как я могу получить основную электронную почту от Пользователя без NHibernate загружает каждое письмо для Пользователя?

У меня есть следующие две сущности, с соответствующей таблицей для каждого

public class User
{
   private readonly IList<Email> _emails;

   public virtual int Id { get; private set; }
   public virtual IEnumerable<Email> Emails { get { return _emails; } }
   // public virtual Email PrimaryEmail { get; set; } - Possible somehow ?
}
public class Email
{
   public virtual int Id { get; private set; }
   public virtual String Address { get; set; }
   public virtual Boolean IsPrimary { get; set; }
   public virtual User User { get; set; }
}

Могу ли я сопоставить свойство «Email PrimaryEmail» и т. Д. Для Пользователя с электронной почтой, для которой каким-либо образом установлено «IsPrimary = 1»? Может быть, с помощью формулы Sql? вид ? отношения один-к-одному? или по-другому?

Должна быть возможность изменить основную электронную почту на другую, поэтому я хотел бы сохранить их в одной таблице и просто изменить свойство IsPrimary.

Используя формулу Sql, можно ли поддерживать свойство «PrimaryEmail» для пользователя в актуальном состоянии, если я устанавливаю для свойства IsPrimary в текущем основном электронном письме значение false, а затем впоследствии устанавливаю для свойства PrimaryEmail значение адрес электронной почты, который должен быть новым основным адресом электронной почты и установить для IsPrimary значение true? Будет ли NHibernate отслеживать изменения в «старом / текущем» основном электронном письме, загруженном формулой Sql? Как насчет кеша 1 уровня и кеша 2 уровня при использовании SqlFormula?

Я не знаю, может ли это работать с использованием View? Тогда я думаю, что электронная почта может быть сопоставлена ​​как компонент? Будет ли это работать при обновлении данных электронной почты при загрузке из представления?

Есть ли лучший способ?

Поскольку у меня двунаправленные отношения между пользователем и электронной почтой, во многих случаях я, конечно, мог запросить основной адрес электронной почты, а затем использовать свойство «Пользователь» в сообщении электронной почты, чтобы получить пользователя (а не наоборот. от пользователя до основного адреса электронной почты)

Надеюсь, кто-нибудь может помочь?

Ответы [ 2 ]

1 голос
/ 09 апреля 2010

Прежде всего. Почему вы используете IEnumerable там? Вы хотите запускать запрос каждый раз, когда к этому свойству обращаются? И почему у него есть публичный сеттер?

Мне кажется, вы хотите, чтобы это был либо IList, либо ICollection. Наличие списка имеет больше смысла, так как я бы добавил два метода:

User.SetPrimary(int index)
User.GetPrimary()
User.ICollection Emails { get; protected set; }

Email.IsPrimary { get; protected set; }

Первая итерация по электронным письмам, чтобы убедиться, что только один элемент установлен в качестве основной, а вторая - итерация по электронной почте, пока не будет найден один элемент, помеченный как основной.

1 голос
/ 09 апреля 2010

На первый взгляд, я бы хотел убедиться, что PrimaryEMail всегда является ссылкой на один из объектов EMail в коллекции (один из способов сделать это - получить / установить полностью на лету ). С таким общедоступным дизайном, как у вас, вы должны будете связать изменения с обработчиком событий в EMail и / или коллекции. Новый первичный объект электронной почты (что-то в коллекции, которую вы продвигаете в первичную) будет знать о своей родительской коллекции или о пользователе, поэтому должен быть в состоянии найти текущий первичный, чтобы сделать его вторичным.

В качестве альтернативы можно сделать IsPrimary не публичным или вообще не раскрывать его публично (email.IsPrimary будет заменен на email == user.PrimaryEMail). Метод набора PrimaryEMail может принимать только объект EMail, уже находящийся в коллекции.

Я делал это только в ручных классах ORM и не смог найти канонический метод для выполнения этого довольно распространенного сценария в NHibernate. Там должен быть один.

...