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.) IQueryable
'ı ICacheQueryable
'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.