Насколько я понимаю, в некотором корпоративном коде C # есть способ преобразовать LINQ-запросы в AST, которые затем переводятся в SQL или что-то подобное, используя IQueryable
и Expression
.
Это выглядит для меня так:
Код, не обращающий внимания на реализацию БД -> Черная магия -> Оптимизированный SQL
Я бы хотел понять эту черную магию и применить ее к игре. Это мой сценарий:
class Entity { public Vector2 position; }
class Chunk {
const int CHUNK_SIZE = 16;
public Vector2 position; // chunk position is multiple of CHUNK_SIZE
public List<Entity> entities;
}
class World {
public Chunk[,] chunks; // Let's imagine this is a 256x256 array of chunks.
public IEnumerable<Entity> Entities {
get {
return chunks.SelectMany(c => c.entities);
}
}
}
class SomewhereElse {
void NotVerySmartCode() {
var someArbitraryEntities = world.Entities
.Where(e => e.position.x > 213 && e.position.x < 247
&& e.position.y > 198 && e.position.y < 212);
foreach (var e in someArbitraryEntities) { // slooooooow }
}
}
Когда NotVerySmartCode
запрашивает World.Entities
, перечислитель обходит все чанки и все сущности и выполняет лямбду Where
для каждого из них.
Совершенно очевидно, что этот код можно было бы оптимизировать, если бы лямбда Where
выполнялась только на кусках, положение которых было в пределах 208
Есть ли способ интеллектуальной интерпретации LINQ и выполнения этой оптимизации? Могу ли я как-то реализовать IQueriable
и использовать Expression
таким образом, чтобы выполнить какую-то чёрную магию?
Извините, если я не понимаю, но я не понимаю, как LINQ-запросы, аналогичные приведенным выше, могут быть преобразованы в эффективный SQL.