Слушатель / событие NHibernate для замены объекта перед вставкой / обновлением

У меня есть класс компании, в котором есть коллекция Address.

Вот мой класс Address: (написано в верхней части моей головы):

public class Address
{
  public string Civic;
  public string Street;
  public City City;
}

Это класс City:

public class City
{
  public int Id;
  public string Name;
  public string SearchableName{ get { //code } }
}

Адрес сохраняется в его собственной таблице и имеет ссылку на идентификатор города. Город также сохранился в собственном столе.

Имя города для поиска используется для предотвращения некоторых ошибок в городе, который вводит пользователь. Например, если название города - «Монреаль», поисковое имя будет «Монреаль». Если название города - "Сент-Джон", поиск будет доступен для поиска "stjohn" и т. Д.

Он используется в основном для поиска и предотвращения наличия нескольких городов с опечаткой.

Когда я сохраняю адрес, я хочу, чтобы слушатель / событие проверяли, есть ли город уже в базе данных. Если да, то отмените вставку и замените город пользователя на город базы данных. Хотелось бы того же поведения с обновлениями.

Я пробовал это:

public bool OnPreInsert(PreInsertEvent @event)
{
    City entity = (@event.Entity as City);

    if (entity != null)
    {
        if (entity.Id == 0)
        {
            var city = (from c in @event.Session.Linq<City>()
                        where c.SearchableName == entity.SearchableName
                        select c).SingleOrDefault();
            if (city != null)
            {
                //don't know what to do here
                return true;
            }
        }
    }

    return false;
}

Но если в базе данных уже есть Город, я не знаю, что делать. @ event.Entity доступен только для чтения, если я устанавливаю @ event.Entity.Id, я получаю исключение «нулевой идентификатор». Я пытался перехватить вставку / обновление на адресе и на компании, но город, если он был вставлен первым (это логика ...)

Есть предположения?

Спасибо


person vIceBerg    schedule 30.12.2010    source источник
comment
Интересно, почему вы хотите сделать это с помощью прослушивателя событий, а не в той части кода, которая создает объект адреса? Если вы хотите использовать прослушиватель событий, у меня есть предложение, которое будет работать только тогда, когда у адреса есть идентификатор. Есть ли у адреса идентификатор?   -  person Paco    schedule 31.12.2010
comment
Да, у адреса есть идентификатор. Это потому, что Address будет использоваться при добавлении / обновлении компаний, клиентов, пользователей и т. Д. Я хотел бы написать что-нибудь однажды, что будет обрабатываться для каждого случая. И если в будущем я добавлю ссылку на класс адреса в другом классе (скажем ... добавив класс поставщика с адресом), не нужно будет думать о выполнении поиска / замены для этого класса.   -  person vIceBerg    schedule 01.01.2011
comment
Я открыт для любых других решений, кроме событий / слушателей.   -  person vIceBerg    schedule 01.01.2011


Ответы (2)


Вы имеете дело с этим не на том уровне.

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

Перед попыткой вставить новую запись, служба должна попытаться загрузить город по SearchableName, создавая / обновляя его по мере необходимости.

person Diego Mijelshon    schedule 30.12.2010
comment
В моем отображении класс Company отвечает за сохранение адресов. Я добавляю адрес в коллекцию компании (myCie.AddAddress (myNewAddress)), а вызов session.save (myCie) занимается всем. Как я сказал в своем комментарии к @Paco, у клиентов есть адреса, у пользователей есть адреса. Я хотел бы что-то, что будет обрабатывать город адреса в каждом случае. - person vIceBerg; 01.01.2011

Я решил использовать Stored Proc для обработки вставок и обновлений для этого класса.

SP, если доступное для поиска имя уже существует, возвращает его идентификатор. Иначе вставьте.

Работает нормально!

person vIceBerg    schedule 07.01.2011