ORM_Adv_Tutorial 示例的分析与学习(1)

PS:使用默认的SQL Server 2000做数据库。
1.IsBatchUpdate =true | false 的区别
该属性设置是否进行批查询;默认值是true。
例如示例中的这段代码:
 1 user.Birthday  =  DateTime.Now;
 2         user.Profile.ProfileContent  =   " modified profile content " ;
 3         user.Phones[ 0 ].Description  =   " modified phone desc for  home " ;
 4         user.Phones[ 1 ].Description  =   " modified phone desc for  work " ;
 5
 6          // now, because the user is saved before, most real operations are update, insert or update are all transparent to us. we can always easily SAVE them.
 7          // see runtime log for details and compare to those with the first time save.
 8         WriteLine( string .Empty);
 9         WriteLine( " Second Time Save: " );
10         WriteLine( string .Empty);
11         gateway.Save < LocalUser > (user);
IsBatchUpdate=false 的运行时逻辑:
Second Time  Save :

Text      DELETE   FROM   [ LocalUserPhone ]   WHERE   [ ID ]   =   @ID_c011657ac5d44566b5c50774d96adf32       
Parameters:
@ID_c011657ac5d44566b5c50774d96adf32 [ Guid ]   =  fb08c10f - f609 - 4876 - bc7b - dacb3f0b4b8b


Text      DELETE   FROM   [ LocalUserPhone ]   WHERE   [ ID ]   =   @ID_955848d34eae423cbf198a7ca1228d83       
Parameters:
@ID_955848d34eae423cbf198a7ca1228d83 [ Guid ]   =  aae9c0a9 - 9cbc - 4ba3 - a0ea - 6b5528c85643


Text      UPDATE   [ User ]   SET   [ Birthday ]   =   @Birthday   WHERE   [ ID ]   =   @ID_04563787eaaf48a8aa0a7afc165170a8       
Parameters:
@Birthday [ DateTime ]   =   2006 - 11 - 11   1 : 49 : 47
@ID_04563787eaaf48a8aa0a7afc165170a8 [ Guid ]   =  7905c005 - 6192 - 4887 - b7ac - 886a7b045551


Text      UPDATE   [ LocalUserPhone ]   SET   [ Description ]   =   @Description   WHERE   [ ID ]   =   @ID_bc32d84ff6324b35b8e15a012ab0e71c       
Parameters:
@Description [ String ]   =  modified phone  desc   for   home
@ID_bc32d84ff6324b35b8e15a012ab0e71c [ Guid ]   =  aae9c0a9 - 9cbc - 4ba3 - a0ea - 6b5528c85643


Text      UPDATE   [ LocalUserPhone ]   SET   [ Description ]   =   @Description   WHERE   [ ID ]   =   @ID_8847b6d4bb3d4d90b92b2e963c0aebb5       
Parameters:
@Description [ String ]   =  modified phone  desc   for    work
@ID_8847b6d4bb3d4d90b92b2e963c0aebb5 [ Guid ]   =  fb08c10f - f609 - 4876 - bc7b - dacb3f0b4b8b


Text      UPDATE   [ UserProfile ]   SET   [ ProfileContent ]   =   @ProfileContent   WHERE   [ ID ]   =   @ID_689ed0c5defc4ae0b7380674e4477bf3       
Parameters:
@ProfileContent [ String ]   =  modified profile content
@ID_689ed0c5defc4ae0b7380674e4477bf3 [ Guid ]   =  7b3185c0 - c216 - 4cd0 - aef9 - c3fe97a57841
显然,每个操作都是单独进行一次数据库操作的。
接着看IsBatchUpdate=false的运行时逻辑:
Second Time  Save :

Text      DELETE   FROM   [ LocalUserPhone ]   WHERE   [ ID ]   =   ' 5cefdd4f-c9d6-4faf-85cd-6cc82471c8f7 '   ;  DELETE   FROM   [ LocalUserPhone ]   WHERE   [ ID ]   =   ' 3286192d-ab59-4bc0-a196-53e6d19fe86e '   ;  UPDATE   [ User ]   SET   [ Birthday ]   =   ' 2006-11-11 1:57:39 '   WHERE   [ ID ]   =   ' d9394b00-20cf-4201-8be6-3c7da70b1f13 '   ;  UPDATE   [ LocalUserPhone ]   SET   [ Description ]   =  N ' modified phone desc for  home '   WHERE   [ ID ]   =   ' 3286192d-ab59-4bc0-a196-53e6d19fe86e '   ;  UPDATE   [ LocalUserPhone ]   SET   [ Description ]   =  N ' modified phone desc for  work '   WHERE   [ ID ]   =   ' 5cefdd4f-c9d6-4faf-85cd-6cc82471c8f7 '   ;  UPDATE   [ UserProfile ]   SET   [ ProfileContent ]   =  N ' modified profile content '   WHERE   [ ID ]   =   ' a3235692-0b60-457e-a0c5-81d276482237 '   ; 
全部操作都在一次数据库操作中完成。
这里有个疑问,更新UserPhone为什么要先删除原先的UserPhone呢?记录删除了,还能更新?
PS:在V3.2.1的更新中已经修改此Bug.

2.关联删除
示例中的这段删除代码:
1         WriteLine( string .Empty);
2         WriteLine( " Then Delete: " );
3         WriteLine( string .Empty);
4         gateway.Delete < LocalUser > (user);
运行时逻辑:
Then   Delete :

Text      SELECT   [ ID ] , [ ProfileContent ] , [ UserID ]   FROM   [ UserProfile ]   WHERE   [ UserID ]   =   @ID     
Parameters:
@ID [ Guid ]   =  8956d9c4 - fc3c - 469a - 8e9c - 57c645fe69e2


Text      SELECT   [ ID ] , [ Description ] , [ Number ] , [ UserID ]   FROM   [ LocalUserPhone ]   WHERE   [ UserID ]   =   @ID     
Parameters:
@ID [ Guid ]   =  8956d9c4 - fc3c - 469a - 8e9c - 57c645fe69e2


Text      DELETE   FROM   [ UserProfile ]   WHERE   [ ID ]   =   ' bbbb863e-6998-48b2-9764-9b0504cbbd03 '   ;  DELETE   FROM   [ LocalUserPhone ]   WHERE   [ ID ]   =   ' 93db36c5-8bfe-4d14-9e76-6f54e40c7708 '   ;  DELETE   FROM   [ LocalUserPhone ]   WHERE   [ ID ]   =   ' 0114dd84-7ab2-4a80-ada1-e581bf849a1c '   ;  DELETE   FROM   [ User ]   WHERE   [ ID ]   =   ' 8956d9c4-fc3c-469a-8e9c-57c645fe69e2 '   ;  DELETE   FROM   [ LocalUser ]   WHERE   [ ID ]   =   ' 8956d9c4-fc3c-469a-8e9c-57c645fe69e2 '   ;     
由于UserPhone和UserProfile都设置了Contained,所以在删除User同时,也会删除它们。而Groups没有设置Contained,所以不会执行同步更新与删除操作。
这里的前两个Select查询,应该是因为LazyLoad=true,在进行删除操作时才第一次使用到UserPhone和UserProfile,所以就会就行Select查询获取它们。

3.Relation属性
User和Group的一对多关系是通过UserGroup来实现的,示例中的代码:
 1     [Relation]
 2      public   interface  UserGroup : NBear.Common.Design.Entity
 3      {
 4        [RelationKey(typeof(User), "ID")]
 5        Guid UserID
 6        {
 7            get;
 8            set;
 9        }

10
11        [RelationKey(typeof(Group), "ID")]
12        Guid GroupID
13        {
14            get;
15            set;
16        }

17    }

User中的Groups属性代码:
1 [Query(RelationType = typeof (UserGroup), OrderBy = " {Name} DESC " , LazyLoad = true )]
2 Group[] Groups
3 {
4     get;
5     set;
6}

设置了LazyLoad=true,和RelationType。
先来看看这段代码:
        WriteLine( string .Empty);
        WriteLine(
" Find the saved local user as user: " );
        WriteLine(
string .Empty);
        User user 
=  gateway.Find < User > (localUser.ID);
        WriteLine(
" The found user: " );
        WriteLine(SerializationManager.Serialize(user));
运行逻辑:
Find the saved local  user   as   user :

Text      SELECT   [ ID ] , [ Name ] , [ Status ] , [ Birthday ]   FROM   [ User ]   WHERE   [ ID ]   =   @ID_f7b6527dbe0443efb1e4c169ed05565e       
Parameters:
@ID_f7b6527dbe0443efb1e4c169ed05565e [ Guid ]   =  eaea2eb0 - a039 - 45a4 - 958f - 610521863f71


Text      SELECT   [ ID ] , [ ProfileContent ] , [ UserID ]   FROM   [ UserProfile ]   WHERE   [ UserID ]   =   @ID     
Parameters:
@ID [ Guid ]   =  eaea2eb0 - a039 - 45a4 - 958f - 610521863f71


The found 
user :
Text      SELECT   [ ID ] , [ Name ] , [ ParentID ]   FROM   [ v_Group_UserGroup ]   WHERE   [ UserGroup_UserID ]   =   @UserGroup_UserID_369b513a1ebd4c2dbf7b6e2ca8bf546a     ORDER   BY   [ Name ]   DESC     
Parameters:
@UserGroup_UserID_369b513a1ebd4c2dbf7b6e2ca8bf546a [ Guid ]   =  eaea2eb0 - a039 - 45a4 - 958f - 610521863f71


< ?xml version = " 1.0 " encoding = "utf - 16 "? >
< User  xmlns:xsi = "http: // www.w3.org / 2001 / XMLSchema - instance" xmlns:xsd = "http: // www.w3.org / 2001 / XMLSchema" >
  
< ID > eaea2eb0 - a039 - 45a4 - 958f - 610521863f71 </ ID >
  
< Name >
    
< FirstName > teddy </ FirstName >
    
< LastName > ma </ LastName >
  
</ Name >
  
< Profile >
    
< ID > 117f29ab - baa6 - 4500 - a670 - c27160394397 </ ID >
    
< ProfileContent >some  sample content </ ProfileContent >
    
< UserID > eaea2eb0 - a039 - 45a4 - 958f - 610521863f71 </ UserID >
  
</ Profile >
  
< Groups  />
  
< Status > Available </ Status >
  
< Birthday xsi:nil = "true"  />
</ User >

第三次的Select查询,是通过查询视图v_Group_UserGroup来获取Groups的。为什么是使用视图来填充的呢?估计这应该就是UserGroup设置了Relation的缘故。比较User和UserPhones的一对多关联,就可以知道。 于我目前只能使用Access作数据库的,不支持视图,所以不应该使用类似UserGroup这类关联 Access同样支持视图查询的。(不知道分析对不对?为了对比在Sql Server和Access中的不同,将会在以后更新中插入对使用Access的分析。)
估计这个Select查询,又是因为LazyLoad的缘故。因为SerializationManager.Serialize(user)操作需要用到Groups属性。
做个测试证明上面的说法,在下Find()之前加上一句判断操作:
         if  (localUser.Groups  ==   null ) ;

        WriteLine(
string .Empty);
        WriteLine(
" Find the saved local user as user: " );
        WriteLine(
string .Empty);
        User user 
=  gateway.Find < User > (localUser.ID);
        WriteLine(
" The found user: " );
        WriteLine(SerializationManager.Serialize(user));

运行时逻辑:
Text      SELECT   [ ID ] , [ Name ] , [ ParentID ]   FROM   [ v_Group_UserGroup ]   WHERE   [ UserGroup_UserID ]   =   @UserGroup_UserID_457cecc48982406fac4bb2726d8af8ce     ORDER   BY   [ Name ]   DESC     
Parameters:
@UserGroup_UserID_457cecc48982406fac4bb2726d8af8ce [ Guid ]   =  eaea2eb0 - a039 - 45a4 - 958f - 610521863f71

Find the saved local 
user   as   user :

看,这个多出来的Select查询再次说明了LazyLoad。

发现结果中好像少了一样,就是UserPhone。在下一篇后续分析中,将会对比FindArray()的运行时逻辑,来看看究竟错误发生在哪里
呵呵,完全是自己不够细心,在Teddy指引下,这里只是Find<User>(),所以是不会有UserPhone的。

今晚暂时到此。。。。
如果大家发现了错误,请即时留言更正,因为小弟才刚刚接触NBear不久,正在努力学习中.......

你可能感兴趣的:(orm)