2011-04-21 78 views
0

为例,假设我的应用程序域是健康俱乐部,客户购买健身房会员资格。这些会员资格包括一系列特权,并且还记录了客户的健康状况。nHibernate with hiLo id generation - 在保存对象图时选择'N + 1'

public class Customer 
    { 
     public int Id { get; set; } 
     public string FullName { get; set; } 
     //... some more properties 
     public Membership Membership { get; set; } 
    } 

class Membership 
{ 
    public DateTime StartDate { get; set; } 
    public DateTime EndDate { get; set; } 
    public FitnessRecord FitnessRecord { get; set; } 
    public IEnumerable<Privilige> MemberPriviliges { get; set; } 

} 

class FitnessRecord 
{ 
    public DateTime Date { get; set; } 
    public int NumberOfPushups { get; set; } 
    //etc... 
} 

class Privilige 
{ 
    public ResourceType Resource { get; set; } //could be 'swimming pool', 'sauna' etc.. 
    public PriviligeType Type { get; set; } //day pass/month pass etc.. 
} 

创建一个新客户时,所有的对象都是instansiated和保存。 我正在使用hiLo生成Id。 这导致了“更新N + 1”的问题,比如:

2011-04-21 17:48:52:468 DEBUG MyApp.Managers - saving Membership with ID 0. 
2011-04-21 17:48:52:484 DEBUG NHibernate.SQL - Reading high value:select next_hi from dbo._uniqueKey with (updlock, rowlock) 
2011-04-21 17:48:52:484 DEBUG NHibernate.SQL - Updating high value:update dbo._uniqueKey set next_hi = @p0 where next_hi = @p1;@p0 = 28735, @p1 = 28734 
2011-04-21 17:48:52:484 DEBUG NHibernate.SQL - Reading high value:select next_hi from dbo._uniqueKey with (updlock, rowlock) 
2011-04-21 17:48:52:484 DEBUG NHibernate.SQL - Updating high value:update dbo._uniqueKey set next_hi = @p0 where next_hi = @p1;@p0 = 28736, @p1 = 28735 
2011-04-21 17:48:52:484 DEBUG NHibernate.SQL - Reading high value:select next_hi from dbo._uniqueKey with (updlock, rowlock) 
2011-04-21 17:48:52:484 DEBUG NHibernate.SQL - Updating high value:update dbo._uniqueKey set next_hi = @p0 where next_hi = @p1;@p0 = 28737, @p1 = 28736 
2011-04-21 17:48:52:500 DEBUG NHibernate.SQL - Reading high value:select next_hi from dbo._uniqueKey with (updlock, rowlock) 
2011-04-21 17:48:52:500 DEBUG NHibernate.SQL - Updating high value:update dbo._uniqueKey set next_hi = @p0 where next_hi = @p1;@p0 = 28738, @p1 = 28737 
2011-04-21 17:48:52:500 DEBUG MyApp.Managers - commiting transaction 
2011-04-21 17:48:52:546 DEBUG NHibernate.SQL - Batch commands: 
command 0:INSERT INTO dbo.[FitnessRecord] (..., ..., ..., ..., ..., ..., Id) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6);@p0 = 21/04/2011 17:48:52, @p1 = 25, @p2 = NULL, @p3 = False, @p4 = NULL, @p5 = 5, @p6 = 28736 

2011-04-21 17:48:52:546 DEBUG NHibernate.SQL - Batch commands: 
command 0:INSERT INTO dbo.[Membership] (..., ..., ..., ..., ..., FitnessRecord_id,..., Id) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7);@p0 = 'Stew', @p1 = 'SIMULATED', @p2 = False, @p3 = '300', @p4 = False, @p5 = 28736, @p6 = 28726, @p7 = 28735 

2011-04-21 17:48:52:546 DEBUG NHibernate.SQL - Batch commands: 
command 0:INSERT INTO dbo.[Privilige] (...,..., ..., ..., ..., ..., ..., ..., ..., Id) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9);@p0 = 'BRS', @p1 = 'DST', @p2 = 'SN', @p3 = 21/04/2011 00:00:00, @p4 = '2056', @p5 = '010A', @p6 = 'M', @p7 = 'A35', @p8 = False, @p9 = 28737 
command 1:INSERT INTO dbo.[Privilige] (...,..., ..., ..., ..., ..., ..., ..., ..., Id) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9);@p0 = 'BRS', @p1 = 'DST', @p2 = 'SN', @p3 = 21/04/2011 00:00:00, @p4 = '02056', @p5 = '010A', @p6 = 'M', @p7 = 'A31', @p8 = False, @p9 = 28742 

2011-04-21 17:48:52:546 DEBUG NHibernate.SQL - Batch commands: 
command 0:INSERT INTO dbo.[Customer] (..., ..., ..., ..., Membership_id, ..., Id) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6);@p0 = 21/04/2011 17:48:52, @p1 = 'ValidEntryScan', @p2 = 'ValidEntryScan', @p3 = False, @p4 = 28735, @p5 = 16, @p6 = 28734 

2011-04-21 17:48:52:546 DEBUG NHibernate.SQL - Batch commands: 
command 0:UPDATE dbo.[FitnessRecord] SET ... = @p0, ...= @p1, ...= @p2, ...= @p3, Membership_id = @p4, ...= @p5 WHERE Id = @p6;@p0 = 21/04/2011 17:48:52, @p1 = 25, @p2 = NULL, @p3 = False, @p4 = 28735, @p5 = 5, @p6 = 28736 

2011-04-21 17:48:52:562 DEBUG NHibernate.SQL - Batch commands: 
command 0:UPDATE dbo.[Privilige] SET Membership_id = @p0 WHERE Id = @p1;@p0 = 28735, @p1 = 28737 
command 0:UPDATE dbo.[Privilige] SET Membership_id = @p0 WHERE Id = @p1;@p0 = 28735, @p1 = 28742 

2011-04-21 17:48:52:562 DEBUG MyApp.Managers - finished 

通知的事实,即使我用配料,它仍然需要〜100毫秒才能将其保存这些记录;这似乎有点过分,不是吗?有什么办法可以改进吗?

+1

对于5次插入和3次更新,100毫秒对我来说似乎并不糟糕。 – 2011-04-21 15:39:41

+1

不是第一个** 78ms **读取/更新的高值,只会发生一次**百次**保存。 – Rippo 2011-04-21 15:41:57

回答

0

没有“更新N + 1”问题。

由于HiLo每max_lo项检索/更新一次,这些语句只会出现在您的第一次执行中,对于以下调用,时间有效为零。

+0

我在每次执行中看到这些语句。你能详细说明'HiLo是否每个max_lo项目检索/更新一次?也许某处我有一个错误的设置? – 2011-04-24 13:09:44

+0

@sJhonny:http://stackoverflow.com/questions/282099/whats-the-hi-lo-algorithm如果你一直看到这是因为你正在重新启动应用程序,或者你将max_lo设置为1 ;这不是对hilo发电机的现实测试。 – 2011-04-24 14:36:41

+0

绝对正确。我将max_lo设置为0,这是我的一个愚蠢的错误。 – 2011-04-26 06:57:02