Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework "Invalid attempt to read when no data is present" with 'large' data on Azure

I am using Entity Framework (v4.0) to connect to SQL Azure (I have the March SDK installed) and getting a InvalidOperationException when trying to query a table. The message of the exception is Invalid attempt to read when no data is present. and the stack trace clearly shows that this is failing internally in EF when it attempts to get the column header:

at System.Data.SqlClient.SqlDataReader.ReadColumnHeader(Int32 i) 
at System.Data.SqlClient.SqlDataReader.IsDBNull(Int32 i) 
at lambda_method(Closure , Shaper ) 
at System.Data.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper) 
at System.Data.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext() 
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) 
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) 
at Service.LoadSettings() in C:\Service.svc.cs 
at SyncInvokeLoadSettings(Object , Object[] , Object[] ) 
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) 
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)

This is specifically related to the data in a column in the second table (Settings in the example below). This works perfectly fine if I query another table (like the Users in the example below) or exclude quering the that column. Example of the code:

using (var db = new DBEntities()) 
{ 
    var users = (from u in db.Users 
                 where u.PK == userid 
                 select u).ToList();

    if (users.Any()) 
    { 
        var selectedUser = users.Single(); 
        if (selectedUser.Password.Equals(passwordHash)) 
        { 
            // ****************************** 
            // * error is on the next line! * 
            // ****************************** 
            var settings = (from s in db.Settings 
                            where s.User == selectedUser.PK 
                            select s).ToList(); 
        } 
    } 
}   

I've tried re-creating the tables, changing tables names, column names and data types and none of it helps. If the table is empty or the column contains a 'small' set of data then it works but the moment I have a single row in it with a 'large' data it fails!

What do I mean by small & large, well they not really smal & large for SQL:

  • 'small' < ~8k
  • 'large' > ~8k

I can confirm the issue is not related to me disposing the context early.


Updates
  1. This is only on read, inserts work fine.
  2. This does not occur when I use LINQ to SQL, just with EF.
  3. Bug logged with Microsoft as I suspect this is not normal behaviour.
like image 862
Robert MacLean Avatar asked Mar 15 '11 11:03

Robert MacLean


2 Answers

Increase the CommandTimeout on the context.

like image 53
Kizedek Avatar answered Sep 22 '22 15:09

Kizedek


I increased the command timeout, and it worked.

using (var db = new DBEntities()) 
{ 
//setting the CommandTimeout before the .ToList()
db.CommandTimeout = 120;

var users = (from u in db.Users 
             where u.PK == userid 
             select u).ToList();

if (users.Any()) 
{ 
    var selectedUser = users.Single(); 
    if (selectedUser.Password.Equals(passwordHash)) 
    { 
        // ****************************** 
        // * error is on the next line! * 
        // ****************************** 
        var settings = (from s in db.Settings 
                        where s.User == selectedUser.PK 
                        select s).ToList(); 
    } 
} 
}   
like image 30
Rob Bramhall Avatar answered Sep 25 '22 15:09

Rob Bramhall