我有一个非常简单的映射,如:
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 */
答案 0 :(得分:1)
好的,我发现了什么问题。在我测试的类中,我已经映射了一个集合,我正在使用该集合的'lazy instantiation',如:
public virtual ISet<Product> Products
{
get { return _products ?? (_products = new HashedSet<Product>(); }
protected set { _products = value;}
}
事实证明,这与NH无关。这个NH用它自己的实现替换你的集合实例的事情让我很烦恼,成为一个NH新手。希望,其他“新手”可以从中吸取教训。如果你想知道在这个问题上你可能做错的一切,请阅读我的帖子。
答案 1 :(得分:-1)
我发现了一个...... 问题出在那里:
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" />