As previously described, Siaqodb optimizes many types of LINQ queries. Several examples of optimized queries are given below to demonstrate extension methods (note, these examples are using the SiaqodbFactory class found on this page):

  • Select(...) The following query will be optimal because it will NOT create any Company objects, it will read ONLY 2 properties values and an anonymous Type will be created with those values.
public void Select()
{
    Siaqodb siaqodb = SiaqodbFactory.GetInstance();
    for (int i = 0; i < 30; i++)
    {
        Developer deve = new Developer() { Age = 18 + i, FirstName = "Devo" + i.ToString(), LastName = "None" };
        siaqodb.StoreObject(deve);
    }
    var query = from Company c in siaqodb select c;

    //same query written using lambda expression arguments
    var q2 = siaqodb.Query<Company>().Select(c => c);
    foreach (Company c in query)
    {
        // do something with c object
    }
}

public void SelectOnlySomeProperties()
{
    Siaqodb siaqodb = SiaqodbFactory.GetInstance();
    var query = from Company c in siaqodb
        select new { Name = c.Name, Phone = c.Phone };

    // same query written using lambda expression arguments
    var q2 = siaqodb.Query<Company>().Select(c => new { Name = c.Name, Phone = c.Phone });
    foreach (var c in query)
    {
        // do something with c object
    }
}
  • Where(...) The following query runs optimized because only Developers objects that match the condition will be created.
public void Where()
{
    Siaqodb siaqodb = SiaqodbFactory.GetInstance();
    var query = from Developer emp in siaqodb
        where emp.Age > 20 && emp.HireDate < new DateTime(2008, 1, 1)
        select emp;

    // same query written in other way using lambda expression arguments
    var q2 = siaqodb.Query<Developer>().Where(emp => emp.Age > 20 && emp.HireDate < new DateTime(2008, 1, 1)); 
    foreach (Developer c in query) 
    { 
        //do something with c object
    } 
} 
  • First(...)
public void First() 
{
    Siaqodb siaqodb = SiaqodbFactory.GetInstance();
    try 
    { 
        Developer first = (from Developer emp in siaqodb
            where emp.Age > 20
            select emp).First();

        // same query written in other way using lambda expression arguments
        Developer first2 = siaqodb.Query<Developer>().Where(emp => emp.Age > 20).First();
        // or similar-> also run optimized:
        Developer first3 = siaqodb.Query<Developer>().First(emp => emp.Age > 20);
    }
    catch (InvalidOperationException ex)
    {
        Log(ex.Message);
    }
}
  • FirstOrDefault(...)
public void FirstOrDefault()
{
    Siaqodb siaqodb = SiaqodbFactory.GetInstance();
    Developer first = (from Developer emp in siaqodb
        where emp.Age > 20
        select emp).FirstOrDefault();

    // same query written in other way using lambda expression arguments
    Developer first2 = siaqodb.Query<Developer>().Where(emp => emp.Age > 20 ).FirstOrDefault();
    // or similar-> also run optimized:
    Developer first3 = siaqodb.Query<Developer>().FirstOrDefault(emp => emp.Age > 20);
}
  • Count(...)
public void Count()
{
    Siaqodb siaqodb = SiaqodbFactory.GetInstance();
    // to count all objects stored in db of a certain Type:
    int nrObjects = siaqodb.Count<Developer>();
    int nrObjects2 = (from Developer e in siaqodb
        where e.Age > 20
        select e).Count();

    // same query written in other way using lambda expression arguments
    int nrObjects3 = siaqodb.Query<Developer>().Where(emp => emp.Age > 20).Count();
    // similar query->same result -> also optimized
    int nrObjects4 = siaqodb.Query<Developer>().Count(emp => emp.Age > 20);
}
  • Any(...)
public void Any()
{
    Siaqodb siaqodb = SiaqodbFactory.GetInstance();
    bool exists = (from Developer e in siaqodb
        where e.Age > 20
        select e).Any();

    // same query written in other way using lambda expression arguments
    bool exists2 = siaqodb.Query<Developer>().Where(emp => emp.Age > 20).Any();
    // similar query->same result -> also optimized
    bool exists3 = siaqodb.Query<Developer>().Any(emp => emp.Age > 20);
}
  • Last(...)
public void Last()
{
    Siaqodb siaqodb = SiaqodbFactory.GetInstance();
    try
    {
        Developer last = (from Developer emp in siaqodb
            where emp.Age > 20
            select emp).Last();

        // same query written in other way using lambda expression arguments
        Developer last2 = siaqodb.Query<Developer>().Where(emp => emp.Age > 20).Last();
        // or similar-> also run optimized:
        Developer last3 = siaqodb.Query<Developer>().Last(emp => emp.Age > 20);
    }
    catch (InvalidOperationException ex)
    {
        Log(ex.Message);
    }
}
  • LastOrDefault(...)
public void LastOrDefault()
{
    Siaqodb siaqodb = SiaqodbFactory.GetInstance();
    Developer last = (from Developer emp in siaqodb
        where emp.Age > 20
        select emp).LastOrDefault();
    // same query written in other way using lambda expression arguments
    Developer last2 = siaqodb.Query<Developer>().Where(emp => emp.Age > 20).LastOrDefault();
    // or similar-> also run optimized:
    Developer last3 = siaqodb.Query<Developer>().LastOrDefault(emp => emp.Age > 20);
}
  • Single(...)
public void Single()
{
    Siaqodb siaqodb = SiaqodbFactory.GetInstance();
    try
    {
        Developer single = (from Developer emp in siaqodb
            where emp.Age > 20
            select emp).Single();

        // same query written in other way using lambda expression arguments
        Developer single2 = siaqodb.Query<Developer>().Where(emp => emp.Age > 20).Single();
        // or similar-> also run optimized:
        Developer single3 = siaqodb.Query<Developer>().Single(emp => emp.Age > 20);
    }
    catch (InvalidOperationException ex)
    {
        Log(ex.Message);
    }
}
  • SingleOrDefault(...)
public void SingleOrDefault()
{
    Siaqodb siaqodb = SiaqodbFactory.GetInstance();
    try
    {
        Developer single = (from Developer emp in siaqodb
            where emp.Age > 20
            select emp).SingleOrDefault();
        // same query written in other way using lambda expression arguments
        Developer single2 = siaqodb.Query<Developer>().Where(emp => emp.Age > 20).SingleOrDefault();
        // or similar-> also run optimized:
        Developer single3 = siaqodb.Query<Developer>().SingleOrDefault(emp => emp.Age > 20);
    }
    catch (InvalidOperationException ex)
    {
        Log(ex.Message);
    }
}
  • Pagination With Skip(...) and Take(...) If you need pagination in your application you can use Skip/Take methods in a optimized way to pull only needed objects from the database; the following query only pull and create 10 objects.
public void PaginationWith_Skip_Take()
{
    Siaqodb siaqodb = SiaqodbFactory.GetInstance();
    var query = (from Developer emp in siaqodb
        where emp.Age > 20
        select emp).Skip(10).Take(10);
    foreach (var c in query)
    {
        // do something with c object
    }
}


Optimization Considerations

Not all LINQ queries may be optimized. Some of them are partially optimized or not optimized at all, however the following examples propose some workarounds and suggestions.

  • Where unoptimized - the following query runs unoptimized. The problem is that the Length property of String is not available until the data is accessed. Siaqodb can only optimize with the following String methods: StartsWith, EndsWith and Contains; all other String methods/properties for object members result in a unoptimized query.
public void Where_UnoptimizedUsingStringMethods()
{
    Siaqodb siaqodb = SiaqodbFactory.GetInstance();
    var query = from Company c in siaqodb
        where c.Phone.Length == 3
        select c;

    // now all Company objects are loaded from database and query fall in LINQ to objects
    foreach (Company c in query)
    {
        //do something with c
    }
}

Important! if those String methods are used for a local variable and NOT to a member of a stored object, the query runs optimized:

string d = "test";
var queryOptimized = from Company c in siaqodb
    where c.Name == d.Substring(2)
    select c;

// the above query runs optimized
foreach (Company c in queryOptimized)
{
    // do something with c
}
  • Where unoptimized 2 The problem with the following example is that TestMet method gets a member of a storable object as argument; now all Employee objects are loaded from database and query will execute LINQ to objects.
public void Where_UnoptimizedUsingLocalMethod()
{
    Siaqodb siaqodb = SiaqodbFactory.GetInstance();
    var query = from Employee e in siaqodb
        where TestMet(e.Age) == 30
        select e;
    foreach (Employee e in query)
    {
       // do something with e
    }
....
}

public int TestMet(int t)
{
    return t + 1;
}

Important: queries that use Methods that are called with arguments that ARE NOT members of stored objects run Optmized. The next query runs optimized:

var queryOptimized = from Employee e in siaqodb
    where e.Age == TestMet(30)
    select e;

foreach (Employee e in queryOptimized)
{
    // do something with e
}
  • Where unoptimized 3 In the following example, all Employee objects are loaded from database and query will execute LINQ to objects:
class BoolAndIntExample
{
    public int OID { get; set; }
    public int SomeInt { get; set; }
    public bool SomeBool { get; set; }
}

public void Where_UnoptimizedUsingUnaryOperator()
{
    Siaqodb siaqodb = SiaqodbFactory.GetInstance();
    for (int i = 0; i < 10; i++)
    { 
        BoolAndIntExample e = new BoolAndIntExample() { SomeBool = i % 2 == 0, SomeInt = i }; 
        siaqodb.StoreObject(e);
    }
     
    // this query run Unoptimized, problem is !(Not) operator 
    var query = from BoolAndIntExample e in siaqodb
        where e.SomeInt>5 && !e.SomeBool
        select e;
    foreach (BoolAndIntExample e in query)
    {
        // do something with e
    }
 }

To optimize the query above, simply use Equal operator:

var queryOptimized = from BoolAndIntExample e in siaqodb
    where e.SomeInt > 5 && e.SomeBool == false
    select e;

foreach (BoolAndIntExample e in query)
{
    // do something with e
}

You will find all of the examples above in our Examples project in the \Examples\NET\NETSiaqodbExample\Examples folder of the Siaqodb Download.