Получить существующую сущность, если она существует, или создать новую - PullRequest
1 голос
/ 30 апреля 2010

Я импортирую данные, которые могут или не могут уже существовать в моей базе данных. Я бы хотел, чтобы NHibernate связывал любые сущности с существующей базой данных, если она существует (возможно, просто установив первичный ключ / идентификатор), или создавал новую, если ее нет. Я использую архитектуру S # arp для моей платформы (MVC 2, NHibernate, Fluent).

Я добавил атрибут [HasUniqueDomainSignature] в класс и атрибут [DomainSignature] в свойствах, которые я хочу использовать для сравнения. Единственный способ, которым я могу думать (это не является приемлемым решением и может даже не работать), заключается в следующем (psuedo C #):

foreach (Book importedBook in importedBooks){
    foreach (Author author in importedBook.Authors){
        if (!author.IsValid()){  // NHibernate Validator will check DomainSignatures
            author = _authorRepository.GetByExample(author);  // This would be to get the db object with the same signature, 
                                 //but I don't think I could even update this as I iterate through it.
        }
}

}

Как видите, это и грязно, и бессмысленно. Добавьте к этому тот факт, что у меня есть полдюжины ассоциаций в Книге (предмет, формат и т. Д.), И это не имеет никакого смысла. Должен быть простой способ сделать это, что я скучаю. Я не новичок в NHibernate, но я определенно не эксперт.

Ответы [ 3 ]

0 голосов
/ 30 апреля 2010

Большинство реализаций базы данных поддерживают условный синтаксис UPDATE-or-INSERT. Например, в Oracle есть команда MERGE . В сочетании с блоком Hibernate <sql-insert> в вашем отображении вы сможете что-то придумать. Я не знаю свободно, но я полагаю, что это тоже поддерживает.

0 голосов
/ 29 мая 2010

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

Вот код, если он может помочь кому-то еще в этой дилемме:

       public TEntity SaveOrUpdate<TEntity>(TEntity entity, bool checkForExistingEntity)
    {
        IRepository<TEntity> repository = new Repository<TEntity>();
        if (checkForExistingEntity) {

            if (entity is Entity) {
                IEnumerable<PropertyInfo> props = (entity as Entity).GetSignatureProperties();
                Dictionary<string, object> parameters =
                    props.ToDictionary(propertyInfo => propertyInfo.Name, propertyInfo => propertyInfo.GetValue(entity, null));
                TEntity duplicateEntity = repository.FindOne(parameters);
                if (duplicateEntity != null) {
                    // Update any properties with the OverwriteOnSaveUpdate attribute
                    foreach (var property in RepositoryHelper.GetUpdatableProperties(typeof(TEntity)))
                    {
                        object initialValue = property.GetValue(entity, null);
                        property.SetValue(duplicateEntity, initialValue, null);
                    }
                    // Fill in any blank properties on db version
                    foreach (var property in typeof(TEntity).GetProperties())
                    {
                        if (property.GetValue(duplicateEntity, null) == null) {
                            object initialValue = property.GetValue(entity, null);
                            property.SetValue(duplicateEntity, initialValue, null);
                        }
                    }
                    return duplicateEntity;
                }
            }
        }
        return SaveOrUpdate(entity);
    }
0 голосов
/ 30 апреля 2010

Возможно, я не понимаю проблему, но как данные «могут существовать или не существовать в базе данных»? Например, если в книге 2 автора, как хранятся отношения на уровне базы данных, если автора не существует?

Кажется, что вы пытаетесь использовать NHibernate для импорта ваших данных (или создания сущности, если она не существует), что кажется неправильным.

...