C# LINQ LongCount: When to Use It
c# linq longcount: Learn when and how to use LongCount in C# LINQ to avoid overflow when counting large collections, and how it differs from Count.
c# linq longcount requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.
When you need to count elements in a LINQ sequence, Count() is the obvious choice. But Count() returns an int, which has a maximum value of about 2.1 billion. For sequences that can exceed that limit, LINQ provides LongCount(), which returns a long. This article explains the difference, when LongCount() is necessary, and how it behaves across different LINQ sources.
The Difference Between Count and LongCount
Both Count() and LongCount() are extension methods defined in System.Linq.Enumerable for IEnumerable<T>. The key difference is the return type: Count() returns int, while LongCount() returns long. For most applications, an int is sufficient. But when you are working with large data sets, such as log files, telemetry streams, or database tables with billions of rows, the int range can be exceeded.
IEnumerable<int> numbers = Enumerable.Range(0, 1000); int count = numbers.Count(); // returns int long longCount = numbers.LongCount(); // returns long
The long type can represent values up to 9,223,372,036,854,775,807, which is far beyond any realistic collection size in memory. However, if you are counting rows from a database via LINQ to SQL or Entity Framework, the query provider translates LongCount() into a SQL COUNT_BIG or equivalent, which returns a 64-bit integer.
When the int Return Type Becomes a Problem
The int overflow is not a theoretical concern. If you call Count() on a sequence that contains more than int.MaxValue elements, the method will throw an OverflowException. This can happen when you are processing a stream that is being read incrementally, or when you are aggregating data from multiple sources.
// This will throw OverflowException if the sequence has more than int.MaxValue elements var hugeSequence = GetHugeSequence(); // IEnumerable<T> with billions of items int total = hugeSequence.Count(); // OverflowException
Using LongCount() avoids this by returning a long. The method internally uses a 64-bit counter, so it can handle sequences larger than 2.1 billion without throwing.
How LongCount Works with Different LINQ Sources
The behavior of LongCount() depends on the underlying data source. For in-memory collections like List<T> or arrays, LongCount() enumerates the sequence and increments a long counter. It does not use the Count property of the collection because that property is an int. This means that even if a List<T> has a Count property, LongCount() will still iterate through the entire list.
List<int> list = new List<int> { 1, 2, 3 }; long count = list.LongCount(); // enumerates the list, returns 3
For LINQ to SQL or Entity Framework, the query provider translates LongCount() into a SQL COUNT_BIG query. This is efficient because the database server performs the count, and the result is returned as a 64-bit integer. In contrast, Count() translates to COUNT(*) which returns an int in SQL Server, and might cause an overflow if the table has more than 2.1 billion rows.
Performance Considerations: Count vs LongCount
In-memory, LongCount() is slightly slower than Count() because it uses a long accumulator, which on 32-bit systems might involve more CPU instructions. However, the difference is negligible for most applications. The real performance difference appears when you use Count() on a collection that implements ICollection<T>. In that case, Count() optimizes by returning the Count property directly, without enumerating the sequence. LongCount() does not have this optimization because the Count property is an int. So for a List<T>, Count() is O(1), while LongCount() is O(n).
List<int> list = new List<int> { 1, 2, 3 }; int fastCount = list.Count(); // O(1) - uses ICollection<T>.Count long slowCount = list.LongCount(); // O(n) - enumerates the list
If you have a collection that implements ICollection<T> and you are certain the count fits in an int, use Count() for better performance. Use LongCount() only when the count might exceed int.MaxValue or when you need a long result for consistency.
Using LongCount with Predicates
Both Count() and LongCount() have overloads that accept a predicate. The predicate filters the sequence, and the method counts the elements that satisfy the condition. The return type difference remains the same.
IEnumerable<int> numbers = Enumerable.Range(0, 1000000); long evenCount = numbers.LongCount(n => n % 2 == 0);
This is useful when you are counting filtered results from a large dataset. The predicate is applied during enumeration, so no intermediate collection is created.
Practical Example: Large Dataset Counting
Consider a scenario where you are processing a file that contains millions of records. You want to count the number of records that meet a certain condition. Using LongCount() ensures that the count does not overflow even if the file has more than 2.1 billion lines.
using (var reader = new StreamReader("largefile.log")) { long errorCount = 0; string line; while ((line = reader.ReadLine()) != null) { if (line.Contains("ERROR")) { errorCount++; } } }
If you were to use LINQ to read the file, you could use File.ReadLines() which returns an IEnumerable<string>, and then call LongCount() with a predicate.
long errorCount = File.ReadLines("largefile.log") .LongCount(line => line.Contains("ERROR"));
This approach is memory-efficient because File.ReadLines() streams the file line by line, and LongCount() only keeps a running total.
Choosing Between Count and LongCount in Real Code
The decision comes down to the maximum possible size of the sequence and the type of the result you need. If you are counting elements in a collection that is guaranteed to be small, or if you are using a collection that implements ICollection<T> and you want the O(1) optimization, use Count(). If the sequence could exceed int.MaxValue, or if you are working with a database query that might return a large number of rows, use LongCount().
Another consideration is API design. If your method returns a count to a caller, and the caller might need to handle more than 2.1 billion items, returning a long is safer. For example, a method that returns the total number of records in a data store should use long to avoid overflow in the future.
public long GetTotalRecordCount() { using (var context = new AppDbContext()) { return context.Records.LongCount(); } }
By using LongCount(), you make the method future-proof and avoid an OverflowException when the table grows.