Comments 25
ПС: ну да, у постгре то лимита нет, ему проще =)
Поддерживаю! Вообще непонятно к чему такие извращения, когда все решается обычными средствами базы.
Или вы спрашиваете зачем вообще нужно EF и вообще LINQ? Тут тоже всё довольно просто: LINQ проверяется компилятором и поддерживает контекстные подсказки в IDE. Да и объектно-реляционное исчисление куда ближе к ООП чем принятое в SQL просто реляционное исчисление.
EF решал изначально три задачи — абстракция от движка базы, позволял неосилившим SQL хоть как-то работать с базой и seamless работа с разными источниками. Абстрагироваться от движка значит терять производительность. Вторую цель я вообще принять как валидную не могу (и ее частично решал linq2sql, хоть и криво). А простая работа в общем виде с разными источниками невозможна в принципе. Разумеется я не имею ввиду источники с мизерными 100К записей, которые можно в память выкачать.
Пример эта статья. Вместо того, чтобы использовать временную таблицу для ключей и простой JOIN тут аж 6 способов приведено.
О, коллега, вы тоже сторонник Linq2Sql?
Просто я живу в мире розовых Exadata, Infiniband и прочего злобного энтепрайза. База в несколько терабайт и три сотни таблиц — обычное дело. И вот тут-то и начинаешь думать не только о красоте но и о всяких NFR, которые и начинают ооочень сильно толкать в сторону использования вендорских фич.
MemoryJoin — 3871 s
StoredProc — 2505 s
А почему не рассмотрен вариант с SqlBulkCopy
?
Он загружает любого размера данные во временную таблицу, делает это низкоуровнево и максимально быстро, поддерживает транзакции и вообще!
2. Дальше модификация способа 3. Multiple Contains — Для данных на клиенте считаешь массив uniqHash и делаешь запрос на сервер с одним Contains
Отличная идея! Об этом способе я забыл, спасибо! Хотя у него есть существенный (для меня) недостаток: дело в том, что цены на бумаги могут поступать с опозданием и тогда условие для TradedOn
должно быть не =
, а <=
. И также может потребоваться, чтобы вариант PriceSourceId
был не один. В этом случае реализовать такой запрос, используя хэш будет сложно, если вообще возможно. А в MemoryJoin
можно сделать это как обычно, например так:
var queryData = context.FromLocalList(reducedData);
var pricesQuery = from t in queryData
from p in context.Prices.Where(
x => x.Security.Ticker == t.Ticker &&
(x.PriceSourceId == t.PriceSourceId || x.PriceSourceId == 1) &&
x.TradedOn <= t.TradedOn)
.OrderByDescending(x => x.TradedOn)
.Take(1)
select p;
Вы ж не собираетесь потом использовать весь функционал списка. Почему не что-то попроще? Например .ToArray().
Думаю можно зарегистрировать Complex Type и использовать, либо разложить на несколько примитивных коллекций и джойнить через индексы.
JOIN локальной коллекции и DbSet в Entity Framework