Ana içeriğe geç
Version: 1.0.1

LINQ

Apache Ignite.NET LINQ Provider

Apache Ignite.NET, Ignite SQL API'leri ile entegre bir LINQ sağlayıcısı içerir. Doğrudan SQL sözdizimi ile uğraşmaktan kurtulabilir ve LINQ ile C# dilinde sorgular yazabilirsiniz. Ignite LINQ sağlayıcısı, dağıtık joinler, gruplandırmalar, toplamalar, sıralama ve daha fazlası dahil olmak üzere ANSI-99 SQL'in tüm özelliklerini destekler.

Installation

  • Ignite binary dağıtımını kullanıyorsanız: Apache.Ignite.Linq.dll dosyasına bir referans ekleyin
  • NuGet kullanıyorsanız: Install-Package Apache.Ignite.Linq

Configuration

SQL dizinlerinin normal SQL sorgularıyla aynı şekilde yapılandırılması gerekir, ayrıntılar için Definin Indexes bölümüne bakın.

Usage

Apache.Ignite.Linq.CacheLinqExtensions sınıfı, LINQ sağlayıcısı için bir giriş noktasıdır. AsCacheQueryable yöntemini çağırarak bir Ignite cache’i üzerinden sorgulanabilir bir instance edinin ve üzerinde LINQ kullanın:

ICache<EmployeeKey, Employee> employeeCache = ignite.GetCache<EmployeeKey, Employee>(CacheName);

IQueryable<ICacheEntry<EmployeeKey, Employee>> queryable = cache.AsCacheQueryable();

Employee[] interns = queryable.Where(emp => emp.Value.IsIntern).ToArray();

LINQ'yu AsCacheQueryable() öğesini çağırmadan doğrudan cache instance’ında kullanabilirsiniz. Ancak bu, tüm cache veri kümesini local olarak getiren ve işleyen, çok verimsiz olan LINQ to Objects sorgusuyla sonuçlanacaktır.

Introspection

Ignite LINQ sağlayıcısı, aslında ICache.QueryFields kullanır. Expressionları gerçekleştirmeden önce herhangi bir noktada (ToList, ToArray, vb.) IQueryableICacheQueryable'a çevirerek üretilen SqlFieldsQuery'i inceleyebilirsiniz:

// Create query
var query = ignite.GetCache<EmployeeKey, Employee>(CacheName).AsCacheQueryable().Where(emp => emp.Value.IsIntern);

// Cast to ICacheQueryable
var cacheQueryable = (ICacheQueryable) query;

// Get resulting fields query
SqlFieldsQuery fieldsQuery = cacheQueryable.GetFieldsQuery();

// Examine generated SQL
Console.WriteLine(fieldsQuery.Sql);

// Output: select _T0._key, _T0._val from "persons".Person as _T0 where _T0.IsIntern

Projections

Basit Where sorguları ICacheEntry nesneleri üzerinde çalışır. Key, Value veya Key ve Value alanlarından herhangi birini ayrı ayrı seçebilirsiniz. Anonim türler kullanılarak birden çok alan seçilebilir.

var query = ignite.GetCache<EmployeeKey, Employee>(CacheName).AsCacheQueryable().Where(emp => emp.Value.IsIntern);

IQueryable<EmployeeKey> keys = query.Select(emp => emp.Key);

IQueryable<Employee> values = query.Select(emp => emp.Value);

IQueryable<string> names = values.Select(emp => emp.Name);

var custom = query.Select(emp => new {Id = emp.Key, Name = emp.Value.Name, Age = emp.Value.Age});

Compiled Queries

LINQ sağlayıcısı, expression parsing ve SQL generation’un neden olduğu belirli ek yüke neden olur. Sık kullanılan sorgular için bu ek yükü ortadan kaldırmak isteyebilirsiniz.

Apache.Ignite.Linq.CompiledQuery sınıfı, sorgu derlemesini destekler. Derlenmiş sorguyu temsil edecek yeni bir delegate oluşturmak için Compile methodunu çağırın. Tüm sorgu parametreleri, delegate parametrelerinde olmalıdır.

var queryable = ignite.GetCache<EmployeeKey, Employee>(CacheName).AsCacheQueryable();

// Regular query
var persons = queryable.Where(emp => emp.Value.Age > 21);
var result = persons.ToArray();

// Corresponding compiled query
var compiledQuery = CompiledQuery.Compile((int age) => queryable.Where(emp => emp.Value.Age > age));
IQueryCursor<ICacheEntry<EmployeeKey, Employee>> cursor = compiledQuery(21);
result = cursor.ToArray();

Compilde Query Performance Benchmark;

            Method |      Median |    StdDev |
------------------ |------------ |---------- |
QueryLinq | 175.8261 us | 9.9202 us |
QuerySql | 62.2791 us | 5.4908 us |
QueryLinqCompiled | 57.9274 us | 3.1307 us |

Joins

LINQ sağlayıcısı, birkaç cache’e/tabloya ve node’a yayılan JOIN'leri destekler.

var persons = ignite.GetCache<int, Person>("personCache").AsCacheQueryable();
var orgs = ignite.GetCache<int, Organization>("orgCache").AsCacheQueryable();

// SQL join on Person and Organization to find persons working for Apache
var qry = from person in persons from org in orgs
where person.Value.OrgId == org.Value.Id
&& org.Value.Name == "Apache"
select person

foreach (var cacheEntry in qry)
Console.WriteLine(cacheEntry.Value);

// Same query with method syntax
qry = persons.Join(orgs, person => person.Value.OrgId, org => org.Value.Id,
(person, org) => new {person, org}).Where(p => p.org.Name == "Apache").Select(p => p.person);

Contains

ICollection.Contains desteklenir ve bu, bir Id’ye göre veri almak istediğimizde yararlıdır, örneğin:

var persons = ignite.GetCache<int, Person>("personCache").AsCacheQueryable();
var ids = new int[] {1, 20, 56};

var personsByIds = persons.Where(p => ids.Contains(p.Value.Id));

Bu sorgu … where Id IN (?, ?, ?) komutuna çevrilir. Ancak, değişken argüman numarası nedeniyle bu formun compiled querylerde kullanılamayacağını unutmayın. Daha iyi bir alternatif, ids listesinde Join kullanmaktır:

var persons = ignite.GetCache<int, Person>("personCache").AsCacheQueryable();
var ids = new int[] {1, 20, 56};

var personsByIds = persons.Join(ids,
person => person.Value.Id,
id => id,
(person, id) => person);

Bu LINQ sorgusu geçici bir tablo birleşimine çevrilir: select _T0._KEY, _T0._VAL from "person".Person as _T0 inner join table (F0 int = ?) _T1 on (_T1.F0 = _T0.ID) ve tek bir array parametresine sahiptir, böylece plan düzgün bir şekilde cache’e alınabilir ve compiled querylerde de izin verilir.

Supported SQL Functions

Aşağıda, Ignite LINQ sağlayıcısı tarafından desteklenen .NET methodlarının ve bunların SQL eşdeğerlerinin bir listesi bulunmaktadır.