Выбирает ли NHibernate версию обновления? - PullRequest
2 голосов
/ 23 августа 2011

У меня очень простое сопоставление типа:

public abstract class EntityMap<TEnt, TId, TDto> : ClassMap<TEnt>
    where TEnt: Entity<TId, TDto> 
    where TDto : DataTransferObject<TDto, TId>
{
    protected EntityMap()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.Name).Not.Nullable().Unique().Length(255);
        Version(x => x.Version);
        SelectBeforeUpdate();
    } 

Я использую это сопоставление для выполнения теста вроде:

    [TestMethod]
    public void ThatVersionDoesNotChangedAfterOnlyAReadAction()
    {
        var services = BrandServices.WithDto(BrandTestFixtures.GetDto()).Get();
        Assert.AreEqual(1, services.Version);
        Context.CurrentSession().Transaction.Commit();
        Context.CurrentSession().Transaction.Begin();
        var brand = BrandServices.Brands.Single(x => x.Name == BrandTestFixtures.GetDto().Name);
        Assert.AreEqual(1, brand.Version);
    }

Итак, в этом тесте я создаю объект, сопоставленный скарта сущностей и этот объект вставляется в базу данных.Семантически, должна быть только 1 версия объекта.Однако, то, что происходит, - то, что после фиксации вставленный объект немедленно обновляется с новой версией.Более того, когда я снова получаю объект для проверки версии, версия снова увеличивается.Ожидаемая версия должна быть 1, версия тестового бренда - 3, но в базе данных версия 4!?!?!

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

-- statement #1
select brand0_.Id      as Id0_,
       brand0_.Version as Version0_,
       brand0_.Name    as Name0_
from   [Brand] brand0_

-- statement #2
select brand0_.Id      as Id0_,
       brand0_.Version as Version0_,
       brand0_.Name    as Name0_
from   [Brand] brand0_

-- statement #3
INSERT INTO [Brand]
           (Version,
            Name,
            Id)
VALUES     (1 /* @p0_0 */,
            'Dynatra' /* @p1_0 */,
            '8ca15020-2e23-4ace-adff-9f4800b706d5' /* @p2_0 */)

-- statement #4
UPDATE [Brand]
SET    Version = 2 /* @p0 */,
       Name = 'Dynatra' /* @p1 */
WHERE  Id = '8ca15020-2e23-4ace-adff-9f4800b706d5' /* @p2 */
       AND Version = 1 /* @p3 */

-- statement #5
commit transaction

-- statement #6
begin transaction with isolation level: Unspecified

-- statement #7
UPDATE [Brand]
SET    Version = 3 /* @p0 */,
       Name = 'Dynatra' /* @p1 */
WHERE  Id = '8ca15020-2e23-4ace-adff-9f4800b706d5' /* @p2 */
       AND Version = 2 /* @p3 */

-- statement #8
select brand0_.Id      as Id0_,
       brand0_.Version as Version0_,
       brand0_.Name    as Name0_
from   [Brand] brand0_

-- statement #9
UPDATE [Brand]
SET    Version = 4 /* @p0 */,
       Name = 'Dynatra' /* @p1 */
WHERE  Id = '8ca15020-2e23-4ace-adff-9f4800b706d5' /* @p2 */
       AND Version = 3 /* @p3 */

Ответы [ 2 ]

1 голос
/ 26 августа 2011

Хорошо, я нашел, что было не так.В классе, который я тестировал, я нанёс на карту коллекцию и использовал «ленивый экземпляр» этой коллекции, например:

    public virtual ISet<Product> Products
    {
        get  { return _products ?? (_products = new HashedSet<Product>(); }
        protected set { _products = value;}
    }

Оказывается, что с NH это не получится.Эта вещь, когда NH заменил экземпляр вашей коллекции собственной реализацией, доставила мне много головной боли, будучи новичком NH.Надеюсь, что другие «новички» могут извлечь уроки из этого.Если вы хотите знать все, что вы можете сделать неправильно по этому вопросу, прочитайте мои сообщения.

0 голосов
/ 23 октября 2011

Я нашел также один ... Проблема была там:

public enum ContractValidationImportance
{
    Low,
    Neutral,
    Intermediate,
    High
}

...entity.cs
.....

    private ContractValidationImportance _validationImportance;
    public ContractValidationImportance ValidationImportance
    {
        get { return _validationImportance; }
        set { _validationImportance = value; }
    }

... entity.hbm.xml

<property name="ValidationImportance" column="ValidationImportance" type="Int32" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...