nhibernate:为什么 nhibernate 会更新我的子实体的外键?

发布于 2024-08-17 08:15:52 字数 4599 浏览 3 评论 0原文

好的,我有两个名为 WorkPostSheet 和 WorkPost 的实体,其中 WorkPostSheet 包含 WorkPost-items 的集合:

public class WorkPostSheet
{
    ...

    public virtual IEnumerable<WorkPost> WorkPosts
    {
        get;
        private set;
    }
}

在我的集成测试中,我注意到 nhibernate 创建了一个我无法理解的更新语句。测试:

    [Test]
    public void Commit_CreateNewWorkPostSheetWithWorkPosts_WorkPostsPersisted()
    {
        using (IUnitOfWork unitOfWork = IsolatingFactory.CreateReadOnlyUnitOfWork())
        {
            // arrange
            WorkPostSheetRepository repository = new WorkPostSheetRepository(IsolatingFactory);
            WorkItemRepository workItemRepository = new WorkItemRepository(IsolatingFactory);

            DateTime from = new DateTime(2000, 1, 1);
            DateTime to = new DateTime(2000, 2, 1);
            WorkPostSheet sheetWithWorkPosts = WorkPostSheet.Create(TestData.CreateAndCommitUser("min", "Marius", "Ingjer", IsolatingFactory), new TimePeriod(from, to));

            WorkItem workItemToPostWorkOn = WorkItem.Create(0, "A");
            workItemRepository.Commit(workItemToPostWorkOn);

            WorkPost workPost = sheetWithWorkPosts.Add(workItemToPostWorkOn, from);

            // act
            repository.Commit(sheetWithWorkPosts);
            unitOfWork.Session.Flush();
            unitOfWork.Session.Clear();

            WorkPostSheet sheetWithWorkPostsFromDb = repository.Get(sheetWithWorkPosts.Id, false);

            // assert
            CollectionAssert.Contains(sheetWithWorkPostsFromDb.WorkPosts, workPost);
        }
    }

输出:

NHibernate:插入“用户”(用户名、名字、姓氏)值(@p0、@p1、@p2);选择last_insert_rowid();@p0 = 'min', @p1 = 'Marius', @p2 = 'Ingjer'

这很有意义,因为我正在创建一个用户 (TestData.CreateAndCommitUser)

NHibernate:插入“WorkItem”(LastChanged、描述、Id)值(@p0、@p1、@p2);@p0 = 06.01.2010 21:50:25、@p1 = 'A'、@p2 = 0

这有意义,因为我正在创建一个工作项

NHibernate:插入“WorkPostSheet”(PeriodFrom、PeriodTo、userId)值(@p0、@p1、@p2);选择last_insert_rowid();@p0 = 01.01.2000 00:00:00, @p1 = 01.02.2000 00:00:00, @p2 = 1

这是有道理的,因为我正在创建工作表

NHibernate:插入“WorkPost”(WorkDone、workItemId、sheetId)值(@p0、@p1、@p2);选择last_insert_rowid();@p0 = 0,@p1 = 0,@p2 = 1

这是在 WorkPostRepository 中提交的(工作表是根实体)

NHibernate:更新“WorkPost”SETsheetId = @p0 WHERE Id = @p1;@p0 = 1,@p1 = 1

现在这个我不明白。外部会使用首次提交实体时分配的相同值进行更新。你能帮我理解这一点吗?

NHibernate:选择workpostsh0_.Id作为Id3_1_,workpostsh0_.PeriodFrom作为PeriodFrom3_1_,workpostsh0_.PeriodTo作为PeriodTo3_1_,workpostsh0_.userId作为userId3_1_,user1_.Id作为Id0_0_,user1_.UserName作为UserName0_0_,user1_.FirstName作为FirstName0_0_,user1_。 LastName as LastName0_0_ FROM "WorkPostSheet" workpostsh0_ inside join "User" user1_ on workpostsh0_.userId=user1_.Id WHERE workpostsh0_.Id=@p0;@p0 = 1

从存储库加载

NHibernate:选择workposts0_.sheetId作为sheetId2_,workposts0_.Id作为Id2_,workposts0_.Id作为Id2_1_,workposts0_.WorkDone作为WorkDone2_1_,workposts0_.workItemId作为workItemId2_1_,workposts0_.sheetId作为sheetId2_1_,workitem1_.Id作为Id1_0_, _。 LastChanged 为 LastChan2_1_0_,workitem1_.Description 为 Descript3_1_0_ FROM“WorkPost”workposts0_ 在 workposts0_.workItemId=workitem1_.Id 上内部加入“WorkItem”workitem1_,其中 workposts0_.sheetId=@p0;@p0 = 1

延迟加载

以下是映射文件:

sealed class WorkPostClassMap : ClassMap<WorkPost>
{
    public WorkPostClassMap()
    {
        Not.LazyLoad();

        Id(post => post.Id).GeneratedBy.Identity().UnsavedValue(0);
        Map(post => post.WorkDone);
        References(post => post.Item).Column("workItemId").Not.Nullable();
        References(Reveal.Property<WorkPost, WorkPostSheet>("Owner"), "sheetId").Not.Nullable();
    }
}

sealed class WorkPostSheetClassMap : ClassMap<WorkPostSheet>
{
    public WorkPostSheetClassMap()
    {
        Id(sheet => sheet.Id).GeneratedBy.Identity().UnsavedValue(0);
        Component(sheet => sheet.Period, period =>
                                             {
                                                 period.Map(p => p.From, "PeriodFrom");
                                                 period.Map(p => p.To, "PeriodTo");
                                             });
        References(sheet => sheet.Owner, "userId").Not.Nullable();
        HasMany(sheet => sheet.WorkPosts).KeyColumn("sheetId").AsBag();
    }
}

Ok, i have two entities named WorkPostSheet and WorkPost where the WorkPostSheet contains a collection of WorkPost-items:

public class WorkPostSheet
{
    ...

    public virtual IEnumerable<WorkPost> WorkPosts
    {
        get;
        private set;
    }
}

In my integration test, i notice that nhibernate creates an update statement which I cannot understand. The test:

    [Test]
    public void Commit_CreateNewWorkPostSheetWithWorkPosts_WorkPostsPersisted()
    {
        using (IUnitOfWork unitOfWork = IsolatingFactory.CreateReadOnlyUnitOfWork())
        {
            // arrange
            WorkPostSheetRepository repository = new WorkPostSheetRepository(IsolatingFactory);
            WorkItemRepository workItemRepository = new WorkItemRepository(IsolatingFactory);

            DateTime from = new DateTime(2000, 1, 1);
            DateTime to = new DateTime(2000, 2, 1);
            WorkPostSheet sheetWithWorkPosts = WorkPostSheet.Create(TestData.CreateAndCommitUser("min", "Marius", "Ingjer", IsolatingFactory), new TimePeriod(from, to));

            WorkItem workItemToPostWorkOn = WorkItem.Create(0, "A");
            workItemRepository.Commit(workItemToPostWorkOn);

            WorkPost workPost = sheetWithWorkPosts.Add(workItemToPostWorkOn, from);

            // act
            repository.Commit(sheetWithWorkPosts);
            unitOfWork.Session.Flush();
            unitOfWork.Session.Clear();

            WorkPostSheet sheetWithWorkPostsFromDb = repository.Get(sheetWithWorkPosts.Id, false);

            // assert
            CollectionAssert.Contains(sheetWithWorkPostsFromDb.WorkPosts, workPost);
        }
    }

The output:

NHibernate: INSERT INTO "User" (UserName, FirstName, LastName) VALUES (@p0, @p1, @p2); select last_insert_rowid();@p0 = 'min', @p1 = 'Marius', @p2 = 'Ingjer'

This makes sence since I am creating a user (TestData.CreateAndCommitUser)

NHibernate: INSERT INTO "WorkItem" (LastChanged, Description, Id) VALUES (@p0, @p1, @p2);@p0 = 06.01.2010 21:50:25, @p1 = 'A', @p2 = 0

This makes sence since I am creating a workitem

NHibernate: INSERT INTO "WorkPostSheet" (PeriodFrom, PeriodTo, userId) VALUES (@p0, @p1, @p2); select last_insert_rowid();@p0 = 01.01.2000 00:00:00, @p1 = 01.02.2000 00:00:00, @p2 = 1

This makes sence as I am creating a workpost sheet

NHibernate: INSERT INTO "WorkPost" (WorkDone, workItemId, sheetId) VALUES (@p0, @p1, @p2); select last_insert_rowid();@p0 = 0, @p1 = 0, @p2 = 1

This is commited in the WorkPostRepository (workpost sheet is root entity)

NHibernate: UPDATE "WorkPost" SET sheetId = @p0 WHERE Id = @p1;@p0 = 1, @p1 = 1

Now this one I not understand. The foreign is updated with the same value assigned when the entity was first commited. Can you help me understand this?

NHibernate: SELECT workpostsh0_.Id as Id3_1_, workpostsh0_.PeriodFrom as PeriodFrom3_1_, workpostsh0_.PeriodTo as PeriodTo3_1_, workpostsh0_.userId as userId3_1_, user1_.Id as Id0_0_, user1_.UserName as UserName0_0_, user1_.FirstName as FirstName0_0_, user1_.LastName as LastName0_0_ FROM "WorkPostSheet" workpostsh0_ inner join "User" user1_ on workpostsh0_.userId=user1_.Id WHERE workpostsh0_.Id=@p0;@p0 = 1

Load from repository

NHibernate: SELECT workposts0_.sheetId as sheetId2_, workposts0_.Id as Id2_, workposts0_.Id as Id2_1_, workposts0_.WorkDone as WorkDone2_1_, workposts0_.workItemId as workItemId2_1_, workposts0_.sheetId as sheetId2_1_, workitem1_.Id as Id1_0_, workitem1_.LastChanged as LastChan2_1_0_, workitem1_.Description as Descript3_1_0_ FROM "WorkPost" workposts0_ inner join "WorkItem" workitem1_ on workposts0_.workItemId=workitem1_.Id WHERE workposts0_.sheetId=@p0;@p0 = 1

Lazy load

Here are the mapping files:

sealed class WorkPostClassMap : ClassMap<WorkPost>
{
    public WorkPostClassMap()
    {
        Not.LazyLoad();

        Id(post => post.Id).GeneratedBy.Identity().UnsavedValue(0);
        Map(post => post.WorkDone);
        References(post => post.Item).Column("workItemId").Not.Nullable();
        References(Reveal.Property<WorkPost, WorkPostSheet>("Owner"), "sheetId").Not.Nullable();
    }
}

sealed class WorkPostSheetClassMap : ClassMap<WorkPostSheet>
{
    public WorkPostSheetClassMap()
    {
        Id(sheet => sheet.Id).GeneratedBy.Identity().UnsavedValue(0);
        Component(sheet => sheet.Period, period =>
                                             {
                                                 period.Map(p => p.From, "PeriodFrom");
                                                 period.Map(p => p.To, "PeriodTo");
                                             });
        References(sheet => sheet.Owner, "userId").Not.Nullable();
        HasMany(sheet => sheet.WorkPosts).KeyColumn("sheetId").AsBag();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心房的律动 2024-08-24 08:15:52

您是否将关联的收集端的“inverse”属性设置为“true”?

请参阅:http://ayende.com/Blog/archive/2009/01/18/nh-prof-new-feature-superfluous-ltmany-to-onegt-update.aspx

Did you set the "inverse" attribute to "true" for the collection side of the association?

See: http://ayende.com/Blog/archive/2009/01/18/nh-prof-new-feature-superfluous-ltmany-to-onegt-update.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文