0

I'm doing an EF query with a list which contains many elements and I seem to be coming across the same issue listed here (where SQL Server throws an error because there are too many elements in the IN statement). I was wondering if there is another way to do it.

Would ExecuteStoreQuery or ExecuteStoreCommand work if the command set up a temporary table?

Thanks

Community
  • 1
  • 1
m4rc
  • 2,932
  • 2
  • 22
  • 29

2 Answers2

1

Yep, the best way to select from a large list of keys is to use a temp table.

http://explainextended.com/2009/08/18/passing-parameters-in-mysql-in-list-vs-temporary-table/

If you're using MsSQL and C# then SqlBulkCopy will get your list of keys in the fastest.

    public void bulkCopy(String tmpTableName, DataTable table)
    {
        using (SqlBulkCopy bulkCopy =
                       new SqlBulkCopy((SqlConnection)connection))
        {
            bulkCopy.DestinationTableName = tmpTableName;
            bulkCopy.WriteToServer(table);
        }
    }

Then have a stored procedure to match to the temp table by key.

axle_h
  • 553
  • 1
  • 5
  • 16
0

If that list data comes from a database query, do not call .ToList() on your source query. Instead pass the IQueryable to the query.

var statuses = context.Statuses.Where(o => o.IsActive).Select(o => o.Id);
var data = context.Orders.Where(o => statuses.Contains(o.StatusId));

Alternatively you can use something like this

var sessionId = Guid.NewGuid();
foreach (var s in statusList)
    insert into SearchValues(sessionId, s); // pseudo code

var statuses = context.SearchValues.Where(o => o.SessionId == sessionId).Select(o => o.Id);
var data = context.Orders.Where(o => statuses.Contains(o.StatusId));

delete from SearchValues where SessionId == @sessionId // pseudo code

You might want to do the insert and delete using SQL queries (and not EF context operations) for optimal performance.

Knaģis
  • 20,827
  • 7
  • 66
  • 80