Windows Phone - 使用Sterling数据库几个注意事项

Sterling数据库是一个NoSQL 面向对象的数据库产品,不仅可用于Silverlight for Desktop而且可用于Windows Phone上。最近在一个Windows Phone项目上选择了Sterling作为数据库,主要原因有二:1.支持Linq查询 2.功能全面

 

使用Sterling进行数据存取操作,可参考其User Guide, 在实际项目遇到了一些问题,几个注意事项如下:

 

1. 索引字段的值不能为null,否则保存时会遇到异常。这一点在User Guide中 Index一节中没有提到,CodePlex上的disussion中提到了一个解决方法:在Index定义时指定默认值。例如如下index_GroceryItem_Rating的定义

protected override System.Collections.Generic.List<ITableDefinition> _RegisterTables() { return new List<ITableDefinition> { CreateTableDefinition<Tombstone,bool>(c=>true), CreateTableDefinition<Grocery,int>(g=> g.Id), CreateTableDefinition<GroceryItem,int>(x=> x.Id).WithIndex<GroceryItem,int,int>(index_GroceryItem_GroceryId, x=> x.GroceryId) .WithIndex<GroceryItem,string,int>(index_GroceryItem_Rating, x=> x.Rating?? string.Empty) //index cannot be null, so set default value if null .WithIndex<GroceryItem,int,int>(index_GroceryItem_Quantity, x=> x.Quantity) }; } 

 

2. Save之后使用Flush,以免程序异常终止后导致数据库主键及索引的破坏 参见 User Guide 之 Save

 

3. Auto Identity - 实现自增主键,需要实现一个trigger

public class GroceryTrigger : BaseSterlingTrigger<Grocery, int> { private int _nextId; public GroceryTrigger(int nextId) { _nextId = nextId; } public override bool BeforeSave(Grocery instance) { if (instance.Id < 1) { instance.Id = _nextId++; } return true; } public override void AfterSave(Grocery instance) { return; } public override bool BeforeDelete(int key) { return true; } }  

 

并在程序启动或激活时(Application_Launching与Application_Activated事件中)初始化

private void ActivateEngine() { _engine = new SterlingEngine(); _logger = new SterlingDefaultLogger(SterlingLogLevel.Information); _engine.Activate(); _database = _engine.SterlingDatabase.RegisterDatabase<GroceryDatabase>(); int maxGroceryListId = _database.Query<Grocery, int>().Any() ? (from id in _database.Query<Grocery, int>() select id.Key).Max() + 1 : 1; _database.RegisterTrigger<Grocery, int>(new GroceryDatabase.GroceryTrigger(maxGroceryListId)); } 

 

4. Caching的副作用。如果使用Query语句而不是Load语句获得对象,则获得对象是Cache的版本而不是数据库保存的版本,如果对Cache版本的修改还未通过Save操作提交,则Cache版本与数据库保存的版本是不一致的。不注意这一点可能会遇到一些意想不到的Bug。例如在一个page的view model使用如下Query语句加载了数据:

var items = (from item in App.Database.Query<GroceryItem, int, int>(GroceryDatabase.index_GroceryItem_GroceryId) where item.Index == groceryId select item).ToList(); 

用户通过UI操作,修改了某些数据的值。page中有一个Save按钮和Cancel按钮,如果用户不想保存,选择取消,则对数据的修改没有提交。但是这时候Cache中的值已经改变。如果用户重新进入此page,再执行上面的Query语句,则得到的是Cache中的版本,这就与预期不符了。

 

解决方法是通过Load语句加载数据,保证每次加载的都是数据库中的版本:

var itemIds = (from x in App.Database.Query<GroceryItem, int, int>(GroceryDatabase.index_GroceryItem_GroceryId) where x.Index == groceryId select x.LazyValue.Value.Id).ToList(); foreach (int id in itemIds) { var item = App.Database.Load<GroceryItem>(id); Items.Add(item); } 

 

 

你可能感兴趣的:(windows,数据库,cache,application,query,silverlight,phone)