LINQ
03/02/2023
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 ekleyinNuGet 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.
String.ToLower
LOWER
String.ToUpper
UPPER
String.StartsWith("foo")
LIKE 'foo%'
String.EndsWith("foo")
LIKE '%foo'
String.Contains("foo")
LIKE '%foo%'
String.IndexOf("abc")
INSTR(MyField, 'abc') - 1
String.IndexOf("abc", 3)
INSTR(MyField, 'abc', 3) - 1
String.Substring("abc", 4)
SUBSTRING(MyField, 4 + 1)
String.Substring("abc", 4, 7)
SUBSTRING(MyField, 4 + 1, 7)
String.Trim()
TRIM
String.TrimStart()
LTRIM
String.TrimEnd()
RTRIM
String.Trim('x')
TRIM(MyField, 'x')
String.TrimStart('x')
LTRIM(MyField, 'x')
String.TrimEnd('x')
RTRIM(MyField, 'x')
String.Replace
REPLACE
String.PadLeft
LPAD
String.PadRight
RPAD
Regex.Replace
REGEXP_REPLACE
Regex.IsMatch
REGEXP_LIKE
Math.Abs
ABS
Math.Acos
ACOS
Math.Asin
ASIN
Math.Atan
ATAN
Math.Atan2
ATAN2
Math.Ceiling
CEILING
Math.Cos
COS
Math.Cosh
COSH
Math.Exp
EXP
Math.Floor
FLOOR
Math.Log
LOG
Math.Log10
LOG10
Math.Pow
POWER
Math.Round
ROUND
Math.Sign
SIGN
Math.Sin
SIN
Math.Sinh
SINH
Math.Sqrt
SQRT
Math.Tan
TAN
Math.Tanh
TANH
Math.Truncate
TRUNCATE
DateTime.Year
YEAR
DateTime.Month
MONTH
DateTime.Day
DAY_OF_MONTH
DateTime.DayOfYear
DAY_OF_YEAR
DateTime.DayOfWeek
DAY_OF_WEEK - 1
DateTime.Hour
HOUR
DateTime.Minute
MINUTE
DateTime.Second
SECOND
Last updated
Was this helpful?