db4o Tutorial 翻译(6)

这是接着东成西就的翻译来的。
他的地址: http://www.cnblogs.com/JackyXu/archive/2006/11/10/556689.html(五)
http://www.cnblogs.com/JackyXu/archive/2006/11/10/557168.html(四)
http://www.cnblogs.com/JackyXu/archive/2006/11/10/557168.html(三)
http://www.cnblogs.com/JackyXu/archive/2006/11/13/559747.html(二)
http://www.cnblogs.com/JackyXu/archive/2006/11/13/559747.html(一)

4.3更新结构化对象

要更新db4o的结构化对象,只需要调用Set()方法。
None.gif //  updateCar
None.gif
IObjectSet result  =  db.Get( new  Car( " Ferrari " ));
None.gifCar found 
=  (Car)result.Next();
None.giffound.Pilot 
=   new  Pilot( " Somebody else " 0 );
None.gifdb.Set(found);
None.gifresult 
=  db.Get( new  Car( " Ferrari " ));
None.gifListResult(result);
同时修改Pilot类:
None.gif //  updatePilotSingleSession
None.gif
IObjectSet result  =  db.Get( new  Car( " Ferrari " ));
None.gifCar found 
=  (Car)result.Next();
None.giffound.Pilot.AddPoints(
1 );
None.gifdb.Set(found);
None.gifresult 
=  db.Get( new  Car( " Ferrari " ));
None.gifListResult(result);
很简单是不是?但是小心,有问题!如果我们将这个步骤(Session)拆成两个步骤(Session),将会如何?
首先,我们先修改Pilot,然后再修改他的Car
None.gif //  updatePilotSeparateSessionsPart1
None.gif
IObjectSet result  =  db.Get( new  Car( " Ferrari " ));
None.gifCar found 
=  (Car)result.Next();
None.giffound.Pilot.AddPoints(
1 );
None.gifdb.Set(found);
然后,我们看一下结果:
None.gif //  updatePilotSeparateSessionsPart2
None.gif
IObjectSet result  =  db.Get( new  Car( " Ferrari " ));
None.gifListResult(result);
看,有问题了!

4.3.1. 更新深度
想象一下,假如一个类包含很多子类,子类也包含子类。那么,当你修改这个类的对象的时候,要跟着一起更新很多类:他的子类、孙子类。。。。这样,无疑是低效率的。
所以,在刚才更新的步骤中,我们修改了Pilot的子类--Car。当我们保存修改时,我们叫db4o保存我们的Car对象,就认为db4o还帮我们修改了Pilot。但是,我们刚刚的修改程序和第一个修改程序一样,为什么第一次的修改程序可以真正修改到Pilot?第一次,我们修改后,db4o不会真正的获取修改的Pilot,他只是修改了内存中的同样的一个Pilot,而没有更新入数据库。其实我们看到的修改后的值是一个假象而已。重新运行程序,就会发现修改已经不存在了。
为了灵活的解决这个问题,db4o引进了“更新深度”这个概念,这个概念用来控制对一个对象成员树我们到底更新几层。默认值为1,表示只有原始的String型的变量被更新,而对内部引用的对象不做更新。
db4o让更新在一个“度”的范围内,不会过分,也不会浪费效率。但是我们现在想做的是让db4o更新整个Car的对象,而不是只更新一层。

None.gif //  updatePilotSeparateSessionsImprovedPart1
None.gif
Db4oFactory.Configure().ObjectClass( typeof (Car))
None.gif    .CascadeOnUpdate(
true );

 

None.gif //  updatePilotSeparateSessionsImprovedPart2
None.gif
IObjectSet result  =  db.Get( new  Car( " Ferrari " ));
None.gifCar found 
=  (Car)result.Next();
None.giffound.Pilot.AddPoints(
1 );
None.gifdb.Set(found);

 

None.gif //  updatePilotSeparateSessionsImprovedPart3
None.gif
IObjectSet result  =  db.Get( new  Car( " Ferrari " ));
None.gifListResult(result);


看起来好多了!

注意:设置更新深度的动作一定要写在db4o的Open()之前。
我们将会在以后的章节讲到db4o的更新深度、其他的复杂对象的重点,和各自db4o设置细节。

4.4. 删除结构化对象


就像我们之前用到的,Delete()方法可以删除一个对象。

None.gif //  deleteFlat
None.gif
IObjectSet result  =  db.Get( new  Car( " Ferrari " ));
None.gifCar found 
=  (Car)result.Next();
None.gifdb.Delete(found);
None.gifresult 
=  db.Get( new  Car( null ));
None.gifListResult(result);

很好,Car已经被删除了,那Pilot呢?
None.gif //  retrieveAllPilotsQBE
None.gif
Pilot proto  =   new  Pilot( null 0 );
None.gifIObjectSet result 
=  db.Get(proto);
None.gifListResult(result);
Ok, 这才是我们想要的结果 - 在真实生活中,当一个赛车手的car坏了的时候,我们不希望这个赛车手也消失。但是,当我们希望一个对象被删除了以后,他的子对象也被删除时候,该如何?

4.4.1. 循环删除


哈哈,你已经在猜想,是不是循环删除和循环更新很像呢?对了,让我们来设置db4o的删除深度。
None.gif //  deleteDeepPart1
None.gif
Db4oFactory.Configure().ObjectClass( typeof (Car))
None.gif    .CascadeOnDelete(
true );

None.gif //  deleteDeepPart2
None.gif
IObjectSet result  =  db.Get( new  Car( " BMW " ));
None.gifCar found 
=  (Car)result.Next();
None.gifdb.Delete(found);
None.gifresult 
=  db.Get( new  Car( null ));
None.gifListResult(result);

再次注意:所有的设置都不需在IObjectContainer 打开之前

让我们来看一下Pilot:
None.gif //  retrieveAllPilots
None.gif
Pilot proto  =   new  Pilot( null 0 );
None.gifIObjectSet result 
=  db.Get(proto);
None.gifListResult(result);

4.4.2. 再次回顾循环删除

 

问题--如果孩子对象被删除了,但是这个孩子还有被其他对象引用怎么办?

None.gif //  deleteDeepRevisited
None.gif
IObjectSet result  =  db.Get( new  Pilot( " Michael Schumacher " 0 ));
None.gifPilot pilot 
=  (Pilot)result.Next();
None.gifCar car1 
=   new  Car( " Ferrari " );
None.gifCar car2 
=   new  Car( " BMW " );
None.gifcar1.Pilot 
=  pilot;
None.gifcar2.Pilot 
=  pilot;
None.gifdb.Set(car1);
None.gifdb.Set(car2);
None.gifdb.Delete(car2);
None.gifresult 
=  db.Get( new  Car( null ));
None.gifListResult(result);

 

None.gif //  retrieveAllPilots
None.gif
Pilot proto  =   new  Pilot( null 0 );
None.gifIObjectSet result 
=  db.Get(proto);
None.gifListResult(result);

我们有一个问题了:手边没有合适的解决方案。db4o在删除一个对象的时候,不会去检查是不是有别的对象引用了它,所以呢,要十分小心。
让我们在进入下一章以前清理一下数据库

None.gif //  deleteAll
None.gif
IObjectSet result  =  db.Get( typeof (Object));
None.gif
foreach  ( object  item  in  result)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    db.Delete(item);
ExpandedBlockEnd.gif}


 

4.5. 总结


对象之间的关系有如下内容:我们可以钩住一个根对象,找到它的引用图,制定查询。但是当某个对象里面有像数组、集合等的多值成员的时候该怎么办?见下一章

4.6. Full source


 

None.gif 锘縰sing System;
None.gif
using  System.IO;
None.gif
using  Db4objects.Db4o;
None.gif
using  Db4objects.Db4o.Query;
None.gif
namespace  Db4objects.Db4o.Tutorial.F1.Chapter2
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {    
InBlock.gif    
public class StructuredExample : Util
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public static void Main(String[] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            File.Delete(Util.YapFileName);
InBlock.gif            
InBlock.gif            IObjectContainer db 
= Db4oFactory.OpenFile(Util.YapFileName);
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                StoreFirstCar(db);
InBlock.gif                StoreSecondCar(db);
InBlock.gif                RetrieveAllCarsQBE(db);
InBlock.gif                RetrieveAllPilotsQBE(db);
InBlock.gif                RetrieveCarByPilotQBE(db);
InBlock.gif                RetrieveCarByPilotNameQuery(db);
InBlock.gif                RetrieveCarByPilotProtoQuery(db);
InBlock.gif                RetrievePilotByCarModelQuery(db);
InBlock.gif                UpdateCar(db);
InBlock.gif                UpdatePilotSingleSession(db);
InBlock.gif                UpdatePilotSeparateSessionsPart1(db);
InBlock.gif                db.Close();
InBlock.gif                db
=Db4oFactory.OpenFile(Util.YapFileName);
InBlock.gif                UpdatePilotSeparateSessionsPart2(db);
InBlock.gif                db.Close();
InBlock.gif                UpdatePilotSeparateSessionsImprovedPart1(db);
InBlock.gif                db
=Db4oFactory.OpenFile(Util.YapFileName);
InBlock.gif                UpdatePilotSeparateSessionsImprovedPart2(db);
InBlock.gif                db.Close();
InBlock.gif                db
=Db4oFactory.OpenFile(Util.YapFileName);
InBlock.gif                UpdatePilotSeparateSessionsImprovedPart3(db);
InBlock.gif                DeleteFlat(db);
InBlock.gif                db.Close();
InBlock.gif                DeleteDeepPart1(db);
InBlock.gif                db
=Db4oFactory.OpenFile(Util.YapFileName);
InBlock.gif                DeleteDeepPart2(db);
InBlock.gif                DeleteDeepRevisited(db);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                db.Close();
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void StoreFirstCar(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Car car1 
= new Car("Ferrari");
InBlock.gif            Pilot pilot1 
= new Pilot("Michael Schumacher"100);
InBlock.gif            car1.Pilot 
= pilot1;
InBlock.gif            db.Set(car1);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void StoreSecondCar(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Pilot pilot2 
= new Pilot("Rubens Barrichello"99);
InBlock.gif            db.Set(pilot2);
InBlock.gif            Car car2 
= new Car("BMW");
InBlock.gif            car2.Pilot 
= pilot2;
InBlock.gif            db.Set(car2);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
public static void RetrieveAllCarsQBE(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Car proto 
= new Car(null);
InBlock.gif            IObjectSet result 
= db.Get(proto);
InBlock.gif            ListResult(result);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void RetrieveAllPilotsQBE(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Pilot proto 
= new Pilot(null0);
InBlock.gif            IObjectSet result 
= db.Get(proto);
InBlock.gif            ListResult(result);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void RetrieveCarByPilotQBE(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Pilot pilotproto 
= new Pilot("Rubens Barrichello",0);
InBlock.gif            Car carproto 
= new Car(null);
InBlock.gif            carproto.Pilot 
= pilotproto;
InBlock.gif            IObjectSet result 
= db.Get(carproto);
InBlock.gif            ListResult(result);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void RetrieveCarByPilotNameQuery(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IQuery query 
= db.Query();
InBlock.gif            query.Constrain(
typeof(Car));
InBlock.gif            query.Descend(
"_pilot").Descend("_name")
InBlock.gif                .Constrain(
"Rubens Barrichello");
InBlock.gif            IObjectSet result 
= query.Execute();
InBlock.gif            ListResult(result);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void RetrieveCarByPilotProtoQuery(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IQuery query 
= db.Query();
InBlock.gif            query.Constrain(
typeof(Car));
InBlock.gif            Pilot proto 
= new Pilot("Rubens Barrichello"0);
InBlock.gif            query.Descend(
"_pilot").Constrain(proto);
InBlock.gif            IObjectSet result 
= query.Execute();
InBlock.gif            ListResult(result);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void RetrievePilotByCarModelQuery(IObjectContainer db) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IQuery carQuery 
= db.Query();
InBlock.gif            carQuery.Constrain(
typeof(Car));
InBlock.gif            carQuery.Descend(
"_model").Constrain("Ferrari");
InBlock.gif            IQuery pilotQuery 
= carQuery.Descend("_pilot");
InBlock.gif            IObjectSet result 
= pilotQuery.Execute();
InBlock.gif            ListResult(result);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void RetrieveAllPilots(IObjectContainer db) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IObjectSet results 
= db.Get(typeof(Pilot));
InBlock.gif            ListResult(results);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
public static void RetrieveAllCars(IObjectContainer db) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IObjectSet results 
= db.Get(typeof(Car));
InBlock.gif            ListResult(results);
ExpandedSubBlockEnd.gif        }

InBlock.gif    
InBlock.gif        
public class RetrieveCarsByPilotNamePredicate : Predicate
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
readonly string _pilotName;
InBlock.gif            
InBlock.gif            
public RetrieveCarsByPilotNamePredicate(string pilotName)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                _pilotName 
= pilotName;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
InBlock.gif            
public bool Match(Car candidate)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return candidate.Pilot.Name == _pilotName;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif    
InBlock.gif        
public static void RetrieveCarsByPilotNameNative(IObjectContainer db) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
string pilotName = "Rubens Barrichello";
InBlock.gif            IObjectSet results 
= db.Query(new RetrieveCarsByPilotNamePredicate(pilotName));
InBlock.gif            ListResult(results);
ExpandedSubBlockEnd.gif        }

InBlock.gif          
InBlock.gif        
public static void UpdateCar(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IObjectSet result 
= db.Get(new Car("Ferrari"));
InBlock.gif            Car found 
= (Car)result.Next();
InBlock.gif            found.Pilot 
= new Pilot("Somebody else"0);
InBlock.gif            db.Set(found);
InBlock.gif            result 
= db.Get(new Car("Ferrari"));
InBlock.gif            ListResult(result);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void UpdatePilotSingleSession(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IObjectSet result 
= db.Get(new Car("Ferrari"));
InBlock.gif            Car found 
= (Car)result.Next();
InBlock.gif            found.Pilot.AddPoints(
1);
InBlock.gif            db.Set(found);
InBlock.gif            result 
= db.Get(new Car("Ferrari"));
InBlock.gif            ListResult(result);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void UpdatePilotSeparateSessionsPart1(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IObjectSet result 
= db.Get(new Car("Ferrari"));
InBlock.gif            Car found 
= (Car)result.Next();
InBlock.gif            found.Pilot.AddPoints(
1);
InBlock.gif            db.Set(found);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void UpdatePilotSeparateSessionsPart2(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IObjectSet result 
= db.Get(new Car("Ferrari"));
InBlock.gif            ListResult(result);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void UpdatePilotSeparateSessionsImprovedPart1(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Db4oFactory.Configure().ObjectClass(
typeof(Car))
InBlock.gif                .CascadeOnUpdate(
true);        
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void UpdatePilotSeparateSessionsImprovedPart2(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IObjectSet result 
= db.Get(new Car("Ferrari"));
InBlock.gif            Car found 
= (Car)result.Next();
InBlock.gif            found.Pilot.AddPoints(
1);
InBlock.gif            db.Set(found);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void UpdatePilotSeparateSessionsImprovedPart3(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IObjectSet result 
= db.Get(new Car("Ferrari"));
InBlock.gif            ListResult(result);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void DeleteFlat(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IObjectSet result 
= db.Get(new Car("Ferrari"));
InBlock.gif            Car found 
= (Car)result.Next();
InBlock.gif            db.Delete(found);
InBlock.gif            result 
= db.Get(new Car(null));
InBlock.gif            ListResult(result);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void DeleteDeepPart1(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Db4oFactory.Configure().ObjectClass(
typeof(Car))
InBlock.gif                .CascadeOnDelete(
true);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void DeleteDeepPart2(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IObjectSet result 
= db.Get(new Car("BMW"));
InBlock.gif            Car found 
= (Car)result.Next();
InBlock.gif            db.Delete(found);
InBlock.gif            result 
= db.Get(new Car(null));
InBlock.gif            ListResult(result);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void DeleteDeepRevisited(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IObjectSet result 
= db.Get(new Pilot("Michael Schumacher"0));
InBlock.gif            Pilot pilot 
= (Pilot)result.Next();
InBlock.gif            Car car1 
= new Car("Ferrari");
InBlock.gif            Car car2 
= new Car("BMW");
InBlock.gif            car1.Pilot 
= pilot;
InBlock.gif            car2.Pilot 
= pilot;
InBlock.gif            db.Set(car1);
InBlock.gif            db.Set(car2);
InBlock.gif            db.Delete(car2);
InBlock.gif            result 
= db.Get(new Car(null));
InBlock.gif            ListResult(result);
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }
    
ExpandedBlockEnd.gif}

None.gif



 

转载于:https://www.cnblogs.com/xxpyeippx/archive/2007/05/06/736966.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值