次のような非常に単純なマッピングがあります。
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 */