WinFS Programming Model


The WinFS programming model includes data access, data manipulation, WinFS data class extensibility, data synchronization, data change notifications, and event prioritization. Data access and data manipulation allow you to create, retrieve, update, and delete data stored within WinFS and to exercise domain-specific behaviors. Data class extensibility enables you to extend WinFS schemas with custom fields and custom types. Data synchronization allows you to synchronize data between WinFS stores and between a WinFS and a non-WinFS store.

The top of the WinFS data model hierarchy is a WinFS service , which is simply an instance of WinFS. One level in the hierarchy from the service is a volume . A volume is the largest autonomous container of items. Each WinFS instance contains one or more volumes . Within a volume are items .

WinFS introduces the item as the new unit of consistency and operation, rather than the file. The storage system stores items. You have rich query ability over items. An item is effectively a base type of the storage system. An item therefore has a set of data attributes and provides a basic query capability.

People typically organize data in the real world according to some system that makes sense in a given domain. All such systems partition data into named groups. WinFS models this notion with the concept of a folder . A folder is a special type of item. There are two types of folders: containment folders and virtual folders .

A containment folder is an item that contains holding links to other items and models the common concept of a file system folder. An item exists as long as at least one holding link references it. Note that a containment folder doesn t directly contain the items logically present in the folder but instead contains links to those items. This allows multiple containment folders to contain the same item.

A virtual folder is a dynamic collection of items. It is a named set of items. You can either enumerate the set explicitly or specify a query that returns the members of the set. A virtual folder specified by a query is quite interesting. When you add a new item to the store that meets the criteria of the query for a virtual folder, the new item is automatically a member of the virtual folder. A virtual folder is itself an item. Conceptually, it represents a set of nonholding links to items, as you can see in Figure 4-1.

click to expand
Figure 4-1: The WinFS data model hierarchy

Sometimes, you need to model a highly constrained notion of containment ”for example, a Microsoft Word document embedded in an e-mail message is, in a sense, bound more tightly to its container than, for example, a file contained within a folder. WinFS expresses this notion by using embedded items . An embedded item is a special kind of link within an item (named Embedded Link) that references another item. The referenced item can be bound to or otherwise manipulated only within the context of the containing item.

Finally, WinFS provides the notion of categories as a way to classify items. You can associate one or more categories with every item in WinFS. WinFS, in effect, tags the category name onto the item. You can then specify the category name in searches. The WinFS data model allows the definition of a hierarchy of categories, thus enabling a tree-like classification of data.

Organizing Information

All these features together allow five ways to organize your information in WinFS:

  • Hierarchical folder-based organization With this approach, you still have the traditional hierarchical folder and item organization structure. All items in a WinFS data store must reside in a container, and one of these container types is a folder.

  • Type-based organization An item is always of a particular type. For example, you have Person items, Photo items, Organization items, and many other available types. You can even create new types and store them in the WinFS data store.

  • Item property “based organization You can view items that have one or more properties set to specified values. This is, in effect, a virtual folder view with a query that returns the items with the specified value for the specified properties.

  • Relationship-based organization You can retrieve items based on their relationship to other items ”for example, a Person can be a member of an Organization, and either one can be organized or searched for in terms of this relationship.

  • Category-based organization You can create and associate any number of user -defined keywords with an item. Subsequently you can retrieve the items that have a specific value for an associated keyword. You won t, however, be able to create categorization taxonomies, so this organization technique is not as powerful as the preceding approaches.

WinFS APIs

WinFS provides three data access APIs: the managed WinFS API, the ADO.NET API, and the Win32 API. The WinFS API is a strongly typed high level API. ADO.NET provides a lower level API for working with data as XML or as tables or rows. Using ADO.NET, you can access data stored in WinFS by using Transact -Structured Query Language (T-SQL) and, when you want, retrieve data in XML using the T-SQL s FOR XML capability. The Win32 API allows access to the files and folders stored in WinFS.

You might prefer to use multiple access patterns to solve a problem. For example, you can issue a T-SQL query that returns a set of contacts as managed objects of the WinFS Contact type. Regardless of the API you use, each API ultimately manipulates data in the WinFS store using T-SQL.

In many cases, you will prefer to use the managed WinFS API. These .NET Framework classes automatically perform the object-relationship mapping needed to translate between object-oriented programming constructs, and they perform the necessary T-SQL to achieve the WinFS data access.

Using the Managed WinFS Classes

The WinFS managed classes reside in the System.Storage namespace and its nested namespaces. Many applications will also use WinFS type definitions from the System.Storage.Core namespace. You can additionally use types from more specialized namespaces. For example, the managed classes that manipulate the system definition of a Contact reside in the System.Storage.Contact namespace. For simplicity, all the code examples in this chapter will use the following set of using declarations:

 using System.Storage; 
using System.Storage.Core;
using System.Storage.Contact;

ItemContext

The WinFS store consists of items organized into folders and categorized. The first step in working with WinFS is to identify the set of items with which you want to work. We call this process binding , and the set of items can be any of the following:

  • An entire volume (also known as the root folder )

  • An identifiable subset of items in a given volume ”for example, a particular containment folder or virtual folder

  • An individual item

  • A WinFS share (which identifies a volume, a folder, a virtual folder, or an individual item)

To bind to a set of items, you create a System.Storage.ItemContext object and connect it to a WinFS data store. Use the static System.Storage.ItemContext. Open helper method to create an ItemContext object.

The following code creates an ItemContext that connects to the default local WinFS volume. The default is the \\ local-computer-name \DefaultStore share:

 System.Storage.ItemContext ctx = System.Storage.ItemContext.Open (); 

ctx.Close();

Alternatively, you can pass a string to the constructor to connect the item context to a specific WinFS store. The following code creates an item context connected to a WinFS share identified by the \\machine\Legal Documents share:

 ItemContext ctx = null; 
try {
ctx = ItemContext.Open (@"\machine\Legal Documents");

}
finally {
if (ctx != null) ctx.Dispose();
}

Be sure to close or dispose of the context object as soon as you finish using it regardless of exceptions. An ItemContext uses significant unmanaged resources ”such as a connection to the store ”that you should free up in a timely manner. To make closing contexts as convenient as possible, the ItemContext class implements the IDisposable interface. Therefore, you can use the C# using statement as shown in the following example to release these resources:

 using (ItemContext ctx = ItemContext.Open (@"D:\MyStore")) { 

}

Storing a New Item in a WinFS Data Store

Every item in a WinFS data store must be a member of a folder of the store. You obtain the root of the folder hierarchy by calling the extremely well-named static method System.Storage.Folder.GetRootFolder . However, there are also several system-defined containers for storing application-specific data. You often use one of the static methods on the UserDataFolder class to retrieve a folder in which you then place new items.

Getting a Folder

In the following example, I ll find the current user s Personal Contacts folder if it exists and create it when it doesn t exist. Note that this is a somewhat contrived example ”the system automatically creates a user s Personal Contacts folder if it doesn t exist when the user first logs into a system ”but it gives me a chance to show how to create an expected folder when it doesn t exist.

 ItemContext ctx = ItemContext.Open (); 
WellKnownFolder contactsFolder =
UserDataFolder.FindUsersWellKnownFolderWithType (ctx,
GeneralCategories.PersonalContactsFolder);

if (contactsFolder == null) {
//create the Personal Contacts folder
Folder userDataFolder = UserDataFolder.FindMyUserDataFolder (ctx);
WellKnownFolder subFolder = new WellKnownFolder (ctx);
CategoryRef category = new CategoryRef (ctx,
GeneralCategories.PersonalContactsFolder);

// Associate the PersonalContactsFolder category to the folder
subFolder.FolderType = category;
userDataFolder.AddMember (subFolder);
ctx.Update();
}

The preceding code does a number of interesting things. First, I try to locate an existing folder contained in the user s personal data folder hierarchy. I m not looking for the folder by a well-known name. Instead, I m locating the folder within the user s personal data tree that has previously been associated with the well-known category PersonalContactsFolder . The shell displays this folder when you select My Contacts.

This folder normally already exists, but when it doesn t, I retrieve the root folder for the user s data hierarchy. I create a new item, of type WellKnownFolder , and then create a reference to a well-known category ”the PersonalContactsFolder category. I then set the type of the new folder to the PersonalContactsFolder category type, and finally, I add the new folder to its containing folder ”the user s personal data root folder. WinFS doesn t save any changes to the data store until you call Update on the item context (which I regularly forget to do).

Of course, this is the verbose way to find the Personal Contacts folder. I wanted to show you how things work. Normally, I d use the following code instead. The FindMyPersonalContactsFolder method finds the existing folder.

 WellKnownFolder userDataFolder = 
UserDataFolder.FindMyPersonalContactsFolder (ctx);

Creating a New Item

As I now have the Personal Contacts folder, it seems appropriate to create a new contact in the folder. In the following example, I ll create a number of Person contacts and add them to the folder:

 Person[] CreateFriends (ItemContext ctx) { 
string[] GivenNames = { "Monica", "Rachel", "Chandler",
"Joey", "Phoebe", "Ross"};
string[] SurNames = { "Uchra", "Emerald", "Ranier",
"Fibonacci", "Smorgasbord", "Uchra"};
Person[] Friends = new Person [GivenNames.Length];

for (int index = 0; index < GivenNames.Length; index++) {
string linkName = GivenNames[index] + " " + SurNames[index];
Person p = Person.CreatePersonalContact (ctx, linkName);
Friends[index] = p;

p.DisplayName = linkName;
FullName fn = p.GetPrimaryName ();
fn.GivenName = GivenNames[index];
fn.Surname = SurNames[index];
}
ctx.Update ();
}

The prior code uses the static Person.CreatePersonalContact method. This method

  • Creates a new Person item in the specified item context

  • Creates a new FolderMember relationship with the specified name that references the Person

  • Adds the FolderMember relationship to the PersonalContactsFolder s Relationship collection

I subsequently update the DisplayName , GivenName , and Surname properties of the Person item. As always, I call Update on the item context to save the changes to the data store.

Let s look more closely at the CreatePersonalContact method. It is equivalent to the following:

 // Find the PersonalContacts folder 
WellKnownFolder contactsFolder =
UserDataFolder.FindUsersWellKnownFolderWithType (ctx,
GeneralCategories.PersonalContactsFolder);
// Create a new Person item
Person p = new Person (ctx);

// Need a folder relationship that references the new Person
FolderMember fm = new FolderMember (p, linkName);
folder.Relationships.Add (fm);
ctx.Update ();

Relationship Items

WinFS defines a relationship data model that allows you to relate items to one another. When you define the schema for a data type, you can define zero or more relationships as part of the schema. For example, the Folder schema defines the FolderMember relationship. The Organization schema defines the Employee relationship. For each such defined relationship, there is a class that represents the relationship itself. This class is derived from the Relationship class and contains members specific to the relationship type. There is also a strongly typed virtual collection class. This class is derived from VirtualRelationshipCollection and allows relationship instances to be created and deleted.

A relationship relates a source item to a target item. In the previous example, the Personal Contacts folder was the source item and the Person item was the target item. The FolderMember relationship basically indicates that the Person item relates to the Personal Contacts folder as a member of the folder.

When you define a relationship, you define whether the relationship keeps the target item in existence ”a holding relationship ” or doesn t keep the target item in existence ”a reference relationship . When you create a holding relationship to a target item, WinFS increments a reference count on the target item. When WinFS deletes a holding relationship it decrements the reference count on the target item. An item no longer exists in the store when its reference count reaches zero. WinFS never alters the reference count of the target when you create or destroy a reference relationship to the target. Therefore, the target item can disappear from the store when its reference count reaches zero and the relationship might refer to a no-longer-existing item.

WinFS defines the FolderMember relationship as a holding relationship. Most other relationship classes are reference relationships.

Folder Items

Now that you know about Link items, I can refine my description of Folder items. A Folder is a WinFS item that has a collection of Link items. The target of each Link item in the collection is a member of the folder. The Folder.Members property represents this collection of links.

Note this gives a WinFS folder much greater flexibility than traditional file system folders. The members of a folder can be file and nonfile items. Multiple links to a particular item can reside in many folders concurrently. In other words, multiple folders can contain the same item.

Other Item Types

Generally, you create other item types in the WinFS store as you did in the previous examples. Each type occasionally has its own special usage pattern. For example, we can have organizations as members of our Personal Contacts folder, so let s create one:

 Organization cp = FindOrCreateOrganization (ctx, "Main Benefit"); 

Organization FindOrCreateOrganization (ItemContext ctx, string orgName) {
Organization o =
Organization.FindOne (ctx, "DisplayName=


Introducing Microsoft WinFX
Introducing WinFX(TM) The Application Programming Interface for the Next Generation of Microsoft Windows Code Name Longhorn (Pro Developer)
ISBN: 0735620857
EAN: 2147483647
Year: 2004
Pages: 83
Authors: Brent Rector

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net