Sledujte nás na YouTube

Sterling: Praktické použitie NoSQL databázy vo Windows Phone 7

NoSQL databázy sú stále populárnejšie už aj vo svete .NETu a svoje využitie určite nájdu aj na platforme WP7. Jednou z týchto databáz je aj Sterling, dostupný pre Silverlight a WP7.

NoSQL databázy sú stále populárnejšie už aj vo svete .NETu a svoje využitie určite nájdu aj na platforme Windows Phone 7. Jednou z týchto databáz je aj Sterling, dostupný pre Silverlight a Windows Phone 7. Dobrý programátor sa pozná aj podľa toho, že si vie na danú úlohu vybrať správny nástroj, ukážem vám preto, na čo sú NoSQL databázy vhodné a ako Sterling použiť. 

Prečo NoSQL databázy 

NoSQL databázy sú často označované aj objektové alebo dokumentové databázy a od klasických SQL databáz sa výrazne líšia. Namiesto tabuliek s presne definovanou štruktúrou (stĺpce, kľúče, vzťahy) obsahujú tabuľky na ukladanie celých objektov. Ideálnym prípadom použitia je napríklad spravodajská aplikácia pracujúca s článkami. Namiesto zložitého a zdĺhavého definovania štruktúry v SQL CE jednoducho definujete tabuľku na uloženie typu ArticleViewModel s kľúčmi ako Id a CategoryId a máte hotovo.  

Sterling 

Sterling je, ako som už spomínal, NoSQL databáza dostupná pre .NET 4, Silverlight 4 a 5 a Windows Phone 7. Jej hlavnou výhodou je minimálna veľkosť assembly (85 KB) aj uložených dát a výrazne vyššia rýchlosť oproti klasickým XML a JSON serializérom (podrobnosti na webe projektu). 

 

Definícia databázy

Na vytvorenie vlastnej databázy je potrebné definovať triedu odvodenú od BaseDatabaseInstance. Vo vlastnej triede je potrebné predefinovať hodnotu vlastnosti Name a metódu RegisterTables: 

{ 
        public const string DATABASE_NAME = "News Database"; 
        public const string ARTICLE_INDEX = "Article_Title_CategoryId"; 
        protected override System.Collections.Generic.List<ITableDefinition> RegisterTables() 
       { 
        } 
         public override string Name 
        { 
            get { return DATABASE_NAME; } 
        } 
}

Vlastnosť Name určuje názov databázy použitý pri jej ukladaní a načítaní a v metóde RegisterTables dochádza k definícií požadovaných tabuliek. Definícia tabuľky pre objekty typu ArticleViewModel indexovaná vlastnosťami Title a CategoryId vyzerá nasledovne:

protected override System.Collections.Generic.List<ITableDefinition> RegisterTables() 
{ 
            return new List<ITableDefinition> 
                        { 
                            CreateTableDefinition<ArticleViewModel, int>(c => c.Id).WithIndex<ArticleViewModel, string, ulong, int>(ARTICLE_INDEX,r => Tuple.Create(r.Title,r.CategoryId)) 
                        }; 
}

Základom je metóda CreateTableDefinition, ktorá vyžaduje typ ukladaného objektu a vlastnosť použitú ako primárny kľúč (v tomto prípade Id). Použitie indexu nie je povinné, mali by ste ho však vytvoriť nad vlastnosťami, podľa ktorých sa budete na záznamy dotazovať. V tomto prípade tvorí index dvojica Title, CategoryId. 

Inicializácia 

Inicializácia databázy by mala prebiehať v App.xaml.cs, nie je to však podmienka. Je potrebné definovať tri statické premenné definujúce engine, logger a samotnú databázu:

private static ISterlingDatabaseInstance _database = null; 
private static SterlingEngine _engine = null; 
private static SterlingDefaultLogger _logger = null;

Na prístup k databáze sa ešte hodí definícia verejnej vlastnosti:

public static ISterlingDatabaseInstance Database 
{ 
    get 
    { 
        return _database; 
     } 
}

Na inicializáciu všetkého potrebného poslúži metóda _ActivateEngine, ktorá by mala byť volaná  v Application_Launching a Application_Activated: 

private void _ActivateEngine() 
{ 
            _engine = new SterlingEngine(); 
            _logger = new SterlingDefaultLogger(SterlingLogLevel.Information); 
            _engine.Activate(); 
            _database = _engine.SterlingDatabase.RegisterDatabase<Database>(new IsolatedStorageDriver()); 
 }

Dôležitý je hlavne posledný riadok a parameter new IsolatedStorageDriver(), ktorý určuje ukladanie databázy do Isolated Storage. Bez tohto parametru je databáza uložená len v pamäti a nie je perzistentná medzi spusteniami aplikácie. 

Pri ukončení a opustení aplikácie (Application_Deactivated, Application_Closing) je potrebné „upratať“:

private void _DeactivateEngine() 
{ 
    _logger.Detach(); 
    _engine.Dispose();  
    _database = null; 
    _engine = null; 
}

 

Uloženie dát 

Ukladanie dát do databázy je jednoduché, stačí zavolať metódu Save a dať jej objekt správneho typu (v tomto príklade ArticleViewModel):

App.Database.Save(item);

 

Dotazovanie 

Dotazovanie nad dátami je možné vykonávať viacerými spôsobmi, záleží, či máte definované nejaké indexy. Bez definovaných indexov (len s primárnym kľúčom Id typu int) prebieha dotazovanie nad

App.Database.Query<ArticleViewModel, int>()

a môžete použiť štandardné LINQ operátory. Vo Where podmienke však môže vystupovať len primárny kľúč, aby bolo zachované Lazy vyhodnocovanie. Naplnenie kolekcie Articles všetkými článkami z databázy môže potom vyzerať takto: 

foreach (var item in App.Database.Query<ArticleViewModel, int>()) 
{ 
    Articles.Add(item.LazyValue.Value); 
}

Všimnite si, že samotný uložený objekt je definovaný až ako vlastnosť LazyValue, ide teda naozaj o dotazovanie len nad primárnym kľúčom. 

Dotazovanie s použitím definovaného indexu je podobne jednoduché. Naplnenie kolekcie Articles článkami len z kategórií definovaných v zozname categories by vyzeralo takto: 

foreach (var item in App.Database.Query<ArticleViewModel, string, ulong, int>(Database.Database.ARTICLE_INDEX).Where(l => categories.Contains(l.Index.Item2))) 
{ 
     Articles.Add(item.LazyValue.Value); 
}

Nevýhodou indexu vo forme dvojice (Tuple) je, že jej jednotlivé členy nie sú pomenované, sú označované len ako Item1, Item2, našťastie sú aspoň typované. 

Záver

Dúfam, že vás tento článok presvedčil, že NoSQL databázy majú svoje miesto a v istých typoch úloh môžu byť aj na Windows Phone 7 výrazne lepšou voľbou ako klasické SQL CE.

O autorovi – Igor Kulman

-Som absolventom softvérového inžinierstva na MFF UK v Prahe a aktuálne pracujem ako Windows Phone 7 vývojár vo firme Inmite. V minulosti som pôsobil v oblasti systémovej integrácie pre korporátnych zákazníkov. Mám skúsenosti s vývojom aplikácií na platformách .NET a PHP a v súčasnosti smerujem k Azure a Windows 8. Svoje názory publikujem na blogu, zopár článkov nájdete aj na Zdrojáku alebo v starších číslach magazínu PC Revue.

Igor Kulman

7 komentářů

  1. Paulos (neregistrovaný)

    Pravda. Sterling jsem jistou chvíli taky používal. Má obrovskou výhodu v tom, že třídy, které s ním chceme používat, nemusíme prakticky nijak upravovat, jak je to nutné třeba u SQL CE; stačí jen definice v jednom souboru. Sterling je též velmi pěkně navržen. Na druhou stranu se třeba index načítá docela dlouho u velké tabulky, jakou jsem měl já, čili jsem nakonec použil SQL CE, kde ta prodleva není.

  2. BEZY (neregistrovaný)

    Trvá mazání hodně položek stejně dlouho jako v SQL CE nebo je rychlejší?

  3. Momentalne pouzivam vsude IsolatedStorage.Settings u WP7 pro ukladani dat – co vyznamne lepsiho navic prinasi SQLite nebo Sterling, abych premigroval?

  4. -pekr- (neregistrovaný)

    To je ale škaredý kód, že se vám chlapi chce furt používat ty objekty :-) O NoSQL jsem spíše jen četl, ale chci se zeptat – co třeba SQLite? Ten taky de-facto nepoužívá typované fieldy v DB, a výkonově mi nepřijde nějak špatný? Používám sice spíše scripting, takže netuším, zdali je SQLite nějak dobře integrován na .Net, ale předpokládám že ano …

    • Paulos (neregistrovaný)

      Objekty jsou náhodou krásné věci. :-) A ne, že by SQLite nešel použít, ale nativní podporu ve WP7 podle mě nemá. Nicméně existuje funkční port: [odkaz] a WP8 mají mít oficiálně podporu SQLite. Takže asi tak. :-)

    • janac_marek (neregistrovaný)

      No píšeš to akokeby .NET bol neobjektovo orientovaný jazyk…

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *