String Contains Examples

ScaleOut Software NamedCache API

StateServer can evaluate Contains methods found in Linq Where clauses on the server. This section illustrates those capabilities through the use of several examples.

String.Contains Example Class Definition

The examples in this section are based on the following class:

[Serializable]
public class Wine
{
    [SossIndex(HashIndexPriority.Hashable)]
    public string Producer { get; set; }

    [SossIndex(HashIndexPriority.Hashable)]
    public decimal Price { get; set; }

    [SossIndex]
    public string Designation { get; set; }

    [SossIndex(HashIndexPriority.Hashable)]
    public string Varietal { get; set; }

    [SossIndex(HashIndexPriority.Hashable)]
    public int Year { get; set; }

    // a non-indexed property - no [SossIndex] attribute
    public string Description { get; set; }
}

We populate a NamedCache instance with the following Wine instances:

namedCache.Add(Guid.NewGuid(), new Wine() { Producer = "Ayres", Price = 22, Designation = "Willamette Valley", Varietal = "Pinot Noir", Year = 2008, Description = "Dark red fruit on the palate, and a smooth finish." });
namedCache.Add(Guid.NewGuid(), new Wine() { Producer = "Ayres", Price = 32, Designation = "Lewis Rogers Lane", Varietal = "Pinot Noir", Year = 2008, Description = "Lush and full, a deeper expression of their Willamette blend. More earth and pie to the cherry pie quality. Full flavor, long, showing the 667 really clearly." });
namedCache.Add(Guid.NewGuid(), new Wine() { Producer = "Ayres", Price = 36, Designation = "Pioneer", Varietal = "Pinot Noir", Year = 2008, Description = "A well balanced pinot that is restrained while a bit acidic. Long finish that continues to evolve for 30+ seconds." });
namedCache.Add(Guid.NewGuid(), new Wine() { Producer = "Brick House", Price = 24, Designation = "Gamay Noir", Varietal = "Gamay Noir", Year = 2008, Description = "Big nose with cedar, red fruit, and plums." });
namedCache.Add(Guid.NewGuid(), new Wine() { Producer = "Haden Fig", Price = 20, Designation = "Willamette Valley", Varietal = "Pinot Noir", Year = 2008, Description = "Debut offering. A terrific value-priced wine." });
namedCache.Add(Guid.NewGuid(), new Wine() { Producer = "Château des Rontets", Price = 26, Designation = "Pouilly-Fuissé Clos Varambon", Varietal = "Chardonnay", Year = 2009 });
namedCache.Add(Guid.NewGuid(), new Wine() { Producer = "Domaine Francois Lamarche", Price = 43, Designation = "Vosne-Romanée (Côte de Nuits)", Varietal = "Pinot Noir", Year = 2005 });
namedCache.Add(Guid.NewGuid(), new Wine() { Producer = "Domaine Lucien Boillot et Fils", Price = 66, Designation = "Gevrey-Chambertin 1er Cru Les Cherbaudes (Côte de Nuits)", Varietal = "Pinot Noir", Year = 2006 });
namedCache.Add(Guid.NewGuid(), new Wine() { Producer = "Soter", Price = 54, Designation = "Brut Rosé", /* no varietal */ Year = 2006 });

Using String.Contains

Consider the following Linq query:

var q1 = from w in namedCache.QueryObjects<Wine>()
         where w.Varietal.Contains("Noir") && w.Price < 25
         select w;

int count1 = q1.Count();

The String property Varietal is annotated with SossIndexAttribute. Consequently, the Contains method will be evaluated on StateServer instance(s) when the query q1 is evaluated.

In this case, evaluating q1.Count() returns 3 corresponding to the wine instances 2008 Ayres Willamette Valley, 2008 Brick House Gamay Noir, and 2008 Haden Fig Willamette Valley.

Note that the 2006 Soter Brut Rosé instance happens to have no Varietal specification. Consequently, the Varietal property in that instance is . In this situation, the Contains implementation executing on StateServer will return false when evaluating Varietal.Contains("Noir") rather than raising an exception as you might otherwise expect.

In the above example, the container for the String.Contains method was a property on the objects being indexed. The implementation also supports having an indexed property as the containee string as follows:

var q2 = from w in namedCache.QueryObjects<Wine>()
         where "Haden Fig#Ayres".Contains(w.Producer) 
         && w.Price < 25
         select w;

int count2 = q2.Count();
In this case, q2 will return 2008 Ayres Willamette Valley and 2008 Haden Fig Willamette Valley so that the value of count2 will be 2.

Similarly, we can use indexed properties as both containers and containees as showin in the following example.

var q3 = from w in namedCache.QueryObjects<Wine>()
         where w.Designation.Contains(w.Varietal)
         select w;

int count3 = q3.Count();
In this case, q3 will return 2008 Brick House Gamay Noir resulting in count3 having the value 1.

If you attempt to use a property not annotated with the SossIndexAttribute attribute, execution of the query will fail at runtime with a NotSupportedException. The following example demonstrates this:

var q4 = from w in namedCache.QueryObjects<Wine>()
         where w.Description.Contains("red")
         select w;

try {
    // Throws NotSupportedException - see above: q4 cannot be
    // evaluated.
    var count4 = q4.Count();
} catch (NotSupportedException) {
}