COUNT (1) в linq [dубликат]

У меня была аналогичная проблема, но я нашел для нее 100% -ное рабочее решение.

  & lt;? php function super_unique ($ array, $ key) {$ temp_array = [];  foreach ($ array as & amp; $ v) {if (! isset ($ temp_array [$ v [$ key]])) $ temp_array [$ v [$ key]] = & amp;  $ V;  } $ array = array_values ​​($ temp_array);  return $ array;  } $ arr = "";  $ Обр [0] [ 'ID'] = 0;  $ Обр [0] [ 'TITEL'] = "ABC";  $ Обр [1] [ 'ID'] = 1;  $ Обр [1] [ 'TITEL'] = "DEF";  $ Обр [2] [ 'ID'] = 2;  $ Обр [2] [ 'TITEL'] = "ABC";  $ Обр [3] [ 'ID'] = 3;  $ Обр [3] [ 'Titel'] = "XYZ";  echo "& lt; pre & gt;";  print_r ($ обр);  echo "unique ********************* & lt; br / & gt;";  print_r (super_unique ($ обр 'Titel'));  ? & GT;   
88
задан NVRAM 22 May 2009 в 18:27
поделиться

7 ответов

Синтаксис запроса:

  var count = (из o в контексте.MyContainer, где o.ID == '1' из t в o.MyTable выберите t) .Count ();   

Синтаксис метода:

  var count = context.MyContainer .Where (o = & gt; o.ID == '1') .SelectMany (o  = & gt; o.MyTable) .Count ()  

Оба генерируют один и тот же SQL-запрос.

103
ответ дан Jerther 15 August 2018 в 20:50
поделиться
  • 1
    Почему SelectMany () ? Это необходимо? Не будет ли это работать без него? – Jo Smo 4 July 2015 в 17:29
  • 2
    @JoSmo, нет, это совершенно другой запрос. – Craig Stuntz 8 July 2015 в 18:28
  • 3
    Спасибо, что объяснил это мне. Просто хотел быть уверенным. :) – Jo Smo 8 July 2015 в 18:39
  • 4
    Как найти номер строки результата поиска (если он существует)? – puretppc 18 March 2016 в 15:00
  • 5
    Можете ли вы сказать мне, почему это отличается от SelectMany? Я не понимаю. Я делаю это без SelectMany, но он становится очень медленным, потому что у меня более 20 миллионов записей. Я попробовал ответ от Ян Чжан и отлично поработал, просто хотел узнать, что делает SelectMany. – mikesoft 20 October 2016 в 17:45

Я думаю, что это должно сработать ...

  var query = from m in context.MyTable, где m.MyContainerId == '1' // или какое бы имя внешнего ключа.  .. выберите m;  var count = query.Count ();   
2
ответ дан bytebender 15 August 2018 в 20:50
поделиться
  • 1
    Это направление, в котором я тоже пошел, но я понимаю, что если вы не добавили его вручную, m будет иметь свойство MyContainer, но MyContainerId не будет. Следовательно, то, что вы хотите изучить, - m.MyContainer.ID. – Kevin 20 May 2009 в 23:14
  • 2
    Если MyContainer является родительским, а MyTable - дочерними элементами отношений, вам необходимо установить эти отношения с каким-то внешним ключом, я не уверен, как еще вы узнаете, какие объекты MyTable, где связаны объекты MyContainer ... Но, может быть, я сделал предположение о структуре ... – bytebender 21 May 2009 в 16:45

Используйте метод ExecuteStoreQuery контекста сущности. Это позволяет избежать загрузки всего набора результатов и десериализации в объекты для простого подсчета строк.

  int count;  используя (var db = new MyDatabase ()) {строка sql = "SELECT COUNT (*) FROM MyTable, где FkId = {0}";  object [] myParams = {1};  var cntQuery = db.ExecuteStoreQuery & lt; int & gt; (sql, myParams);  count = cntQuery.First & lt; int & gt; ();  }  
3
ответ дан goosemanjack 15 August 2018 в 20:50
поделиться
  • 1
    Если вы напишете int count = context.MyTable.Count (m = & gt; m.MyContainerID == '1') , тогда сгенерированный SQL будет похож на то, что вы делаете, но код много лучше. Никакие объекты не загружаются в память как таковые. Попробуйте в LINQPad, если хотите - он покажет вам SQL, используемый под обложками. – Drew Noakes 4 August 2012 в 17:27
  • 2
    Встроенный SQL. , не моя любимая вещь. – Duanne 2 March 2017 в 22:18

Я думаю, вам нужно что-то вроде

  var count = context.MyTable.Count (t = & gt; t.MyContainer.ID == '1');   

(отредактировано для отражения комментариев)

38
ответ дан Kevin 15 August 2018 в 20:50
поделиться
  • 1
    Я считаю, что ему нужен счет MyTable, а не MyContainer ... – bytebender 20 May 2009 в 22:44
  • 2
    Нет, ему нужен счет объектов в MyTable, на которые ссылается одна сущность с ID = 1 в MyContainer – Craig Stuntz 20 May 2009 в 22:47
  • 3
    Кстати, если t.ID является PK, тогда подсчет в приведенном выше коде будет always равным 1. :) – Craig Stuntz 20 May 2009 в 22:50
  • 4
    @Craig, вы правы, я должен был использовать t.ForeignTable.ID. Обновлено. – Kevin 20 May 2009 в 23:07
  • 5
    Ну, это коротко и просто. Мой выбор: var count = context.MyTable.Count (t = & gt; t.MyContainer.ID == '1'); не длинный и уродливый: var count = (from o в контексте. MyContainer, где o.ID == '1' из t в o.MyTable выберите t) .Count (); Но это зависит от стиля кодирования ... – Mantas Janusauskas 8 May 2013 в 13:11

Ну, даже SELECT COUNT (*) FROM Таблица будет довольно неэффективной, особенно на больших таблицах, поскольку SQL Server действительно не может ничего сделать, кроме полного сканирования таблицы (сканирование с кластерным индексом ).

Иногда достаточно знать приблизительное количество строк из базы данных, и в таком случае может быть достаточно:

  SELECT SUM (used_page_count  ) * 8 AS SizeKB, SUM (row_count) AS [RowCount], OBJECT_NAME (OBJECT_ID) AS TableName FROM sys.dm_db_partition_stats WHERE OBJECT_ID = OBJECT_ID ('YourTableNameHere') AND (index_id = 0 ИЛИ index_id = 1) GROUP BY OBJECT_ID  

Это проверит представление динамического управления и извлечет из него количество строк и размер таблицы, учитывая определенную таблицу. Он делает это путем суммирования записей для кучи (index_id = 0) или кластеризованного индекса (index_id = 1).

Это быстро, легко использовать, но не гарантируется точность 100% или обновляться. Но во многих случаях это «достаточно хорошо» (и на сервере накладывается гораздо меньше нагрузки).

Может быть, это сработает и для вас? Конечно, чтобы использовать его в EF, вам придется обернуть это в хранимой процедуре или использовать прямой вызов «Выполнять SQL-запрос».

Marc

8
ответ дан marc_s 15 August 2018 в 20:50
поделиться
  • 1
    Это не будет полное сканирование таблицы из-за ссылки FK в WHERE. Будут сканироваться только данные мастера. Проблема производительности, с которой он столкнулся, заключалась в загрузке данных blob, а не в счетчике записи. Предполагая, что обычно нет десятков тысяч + подробных записей на основную запись, я бы не «оптимизировал», то, что на самом деле не медленное. – Craig Stuntz 21 May 2009 в 13:55
  • 2
    Хорошо, да, в этом случае вы выберете только подмножество - это должно быть хорошо. Что касается данных blob - у меня создалось впечатление, что вы можете установить «отложенную загрузку», на любом столбце в любой из ваших таблиц EF, чтобы избежать его загрузки, чтобы это могло помочь. – marc_s 21 May 2009 в 17:35
  • 3
    Есть ли способ использовать этот SQL с EntityFramework? Во всяком случае, в этом случае мне нужно было знать, что есть соответствующие строки, но я намеренно задал вопрос в более общем плане. – NVRAM 22 May 2009 в 18:38

Как я понимаю, выбранный ответ все еще загружает все связанные тесты. Согласно этому блогу msdn, есть лучший способ.

http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in- ef-feature-ctp5-part-6-load-related-entities.aspx

В частности

  с использованием (var context = new UnicornsContext ()) var  princess = context.Princesses.Find (1);  // Считаем, сколько единорогов принадлежит принцессе var unicornHaul = context.Entry (princess) .Collection (p = & gt; p.Unicorns) .Query () .Count ();  }  
14
ответ дан Quickhorn 15 August 2018 в 20:50
поделиться
  • 1
    Нет необходимости делать дополнительный запрос Find (1) . Просто создайте сущность и прикрепите к контексту: var princess = new PrincessEntity {Id = 1}; context.Princesses.Attach (принцесса); – tenbits 4 February 2016 в 17:27

Это мой код:

  IQueryable & lt; AuctionRecord & gt;  records = db.AuctionRecord;  var count = records.Count ();   

Убедитесь, что переменная определена как IQueryable, а затем, когда вы используете метод Count (), EF выполнит что-то вроде

  select count (*) from.  ..  

В противном случае, если записи определены как IEnumerable, созданный sql будет запрашивать всю таблицу и подсчитывать возвращаемые строки.

9
ответ дан Yang Zhang 15 August 2018 в 20:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: