Simple LINQ query gets NullReferenceException even though SQL Server table has data - c#

I have a simple Linq query that is failing suddenly. This worked up until yesterday and I have not been able to determine the problem.
The query is simply getting a complete view from SQL Server
using(JobEntities JE = new JobEntities())
{
var BatchData = (from x in JE.vwBatchObjectActiveBatches select x).ToList();
}
Starting yesterday this line gets a
NullReferenceException (Object reference not set to an instance of an object)
My suspicion was that a user put in bad data causing the view to fail on SQL Server, but I have checked SQL Server itself and the view runs fine and populates with data.
This query was running in the middle of a larger function loading data from many places, so I have created a test case where I simply load the main window and run this query directly in the code behind to make sure that nothing else is affecting it, and the query still fails. All other Linq queries that I run in this project work still, only this one fails. The app is not under any production right now, and has been static for several months at least.
When I look at the JE in the watch window I can see the vwBatchObjectActiveBatches and it lists 164 records in the Local section -- this matches the view results on SQL Server. Expanding the Results View shows the null error again.
How can I find and fix whatever is causing this query to fail? Why does the results view show an error but the local Line shows the data that I am attempting to get?

It looks like your database returns NULL where Entity Framework does not expect/allow it. Data returned should be in accordance with the definition of its datamodel objects.
Solution: either 'fix' the data, or fix the query that produces it, or change the definition of your datamodel objects to allow NULL for the conflicting field(s).

Related

MVC: Timeout issue

I'm trying to extract the results of a SQL server view in MVC. The view itself is relatively straightforward and UNIONs a couple of tables together - when run it takes around 2 seconds to return its rows. I've added the view to my model in MVC.
In my controller I have the following code, which is designed to return in JSON format the values from the SQL view:-
public JsonResult GetActivity(string LocalIdentifier)
{
return Json(db.Activities.Where(r => r.LocalIdentifier== LocalIdentifier).ToList(), JsonRequestBehavior.AllowGet);
}
When I try to run this, supplying a valid LocalIdentifier nothing happens for a while and then I get an exception (unhandled in user code) in Visual Studio. For reference, this would generally only return between 30 and 50 rows of data from SQL.
Looking at the Inner Exception I get this error:-
"Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding."
I've done something similar elsewhere in my application and it works fine - I can't see anything wrong with my code in MVC. Is there anything else I could look at to help diagnose and fix this issue?
Update
Interestingly I've just changed the code to extract just one row (just to see what happens - see below) and it runs instantly...could this be a problem with ToList()?? Is there another way of achieving what I'm trying to do that I could try?
public JsonResult GetActivity(string LocalIdentifier)
{
return Json(db.Activities.First(r => r.LocalIdentifier== LocalIdentifier), JsonRequestBehavior.AllowGet);
}
you should try running the resulting query directly on the sql server. I expect that the query runs for more then 30s, resulting in a timeout. The default timeout value is 30s, so the behaviour you're seeing is expected.
2 ways to deal with it:
speed up the query (maybe you're missing an index?)
change the default timeout (but this is not the preferred option in my opinion)
It depends on how db.Activities is defined. If it has properties for other entities (meaning other tables in the database) then these could also be loaded by EF, even though you did not specify so explicitly, because JSON is serializing each object and its properties. Half your database or more could end up being loaded, even from a simple statement like this.
This SO question has several answers that may help you understand better what is going on behind the scenes, and then fix it.
Enable profiling and see the query inside
Launch this query in SSMS and build the query execution plan
Analyse the plan and make the updates to the database - change structure, build index, change query
If the query runs fine in DB then it seems something wrong with your ORM side part and you should search for the problem there

Sequence contains no elements... Thing is, I know it should

Background:
Using C# in the ASP.Net code-behind to call a SQL stored procedure via LINQ-to-Entities.
Also, please note that I am a complete newbie to all of this.
Problem:
I'm calling a stored procedure to get the max_length of a column in my database.
It keeps returning "Sequence Contains No Elements" when utilizing .First() and (alternately) the default when using .FirstOrDefault().
The problem is, I know it should be returning the number "4500" as I've run the query in SQL to see what should be there.
Any ideas on why it would be doing this?
I've searched high and low, but I can't find anyone else who has had this problem where they know it should be returning a value.
Code:
short? `shorty = db.sp_GetMaxLength("ApplicantEssay").First();`
The result of the SQL query used in the stored procedure:
Thanks so much for any assistance you can provide!!
Edit:
The only other code involved is the ADO.Net Entity auto-generated code.
At least, it's the only other code that the program steps through when I tried to examine what was going on.
I had a hard time looking at the return and trying to figure it out, but obviously it's returning nothing):
public virtual ObjectResult<Nullable<short>> sp_GetMaxLength(string cOLUMN_NAME)
{
var cOLUMN_NAMEParameter = cOLUMN_NAME != null ?
new ObjectParameter("COLUMN_NAME", cOLUMN_NAME) :
new ObjectParameter("COLUMN_NAME", typeof(string));
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Nullable<short>>("sp_GetMaxLength", cOLUMN_NAMEParameter);
}
Edit #2: I guess I should close this question out.
I messed around with some stuff in sql, then put it back to what I had in the first place and re-executed the stored procedure. Following that, I deleted the Entity Model, reset web.config to its original state pre-model, closed Visual studio, re-opened Visual Studio, and then re-added an ADO.Net Entity Model to the project. I then re-ran the code, stepped through it, and then all of a sudden, "4500" popped up as the returned value.
I am completely flummoxed, since all the code is exactly the same without changes, but I guess that's the power of scrapping and re-starting??? No other explanation, though I hate when it's as simple as that. :-(
Thanks to all who commented. :-)

ASP.NET MVC 3 - Linq to SQL object stored in session

I have a multi-page (multi-view) form in MVC, the results of which will be saved to a single database table.
Code snippet that initializes the linq object in the first page of the form.
public ActionResult MyForm()
{
// returns a Linq object stored in session
Application currentApp = Application.FromSession();
// if null, initialize the object and save to session
if (currentApp == null)
{
currentApp = new Application();
currentApp.SessionSave();
}
return View(currentApp);
}
And here is a sample snippet of code for the final action that updates some data from the strongly-typed model, then triggers the database save.
[HttpPost]
public ActionResult MyForm3(Application app, FormCollection coll)
{
Application currentApp = Application.FromSession();
currentApp.Contact = app.Contact;
currentApp.AddFormToXml(coll);
currentApp.SessionSave();
_db.Applications.InsertOnSubmit(currentApp);
_db.SubmitChanges();
return RedirectToAction("Blah");
}
The problem I'm running into is that the SubmitChanges fails with the error
Cannot insert the value NULL into
column 'ApplicationData', table
'MyTable';
column does not allow nulls. INSERT
fails. The statement has been
terminated.
In this case, ApplicationData is a column of type xml, which LINQ interprets as an XElement object. When I set a breakpoint at SubmitChanges() and check the value of app.ApplicationData, it is clearly populated (non-null), and yet I continue to get this error. My only thought is that I am misunderstanding something with how data contexts work. It only seems to have an issue with this one column though. Is it possible that I need to figure out a way to attach the XElement object (ApplicationData) to my active data context (_db), and if so, how would I go about doing that?
Take a look at the actual SQL generated and sent to the server.
Start up SQL Server Profiler (on the tools menu in SQL Server Management Studio) and start a trace. Run your application until it crashes. Go back to SQL profiler and look at the SQL queries. Seeing things from the SQL end sometimes make it easy to spot the error, e.g. finding out if your are doing several inserts instead of just one.
Well my suggestion to you is to compare the data type of "ApplicationData" column in your Context model and in your database table.
Also please check your LINQ to SQL mappings for this column "AppliationData" again on the datatype itself.
Please update your post if you find anything...
Ok, so in the action method you mentioned can you check if you are calling the InsertOnSumbit Method again anywhere else before you are finally calling db.SubmitChanges()...or if you are calling the InsertOnSubmit method more than once... I think that will cause a problem if you are calling it twice on the same object.
Update:
I did tried a sample with a single table and was able to insert the xml data as mentioned below.
DataClassesDataContext ctx = new DataClassesDataContext();
Application a1 = new Application();
XName n = "dfdsf";
a1.ApplicationData = new XElement(n);
ctx.Applications.InsertOnSubmit(a1);
ctx.SubmitChanges();
so, now the question will be what does your column data looks like??? if you can post the sample content of the application data then it will be helpful. Also how are you setting the ApplicationData property value?

LINQ to SQL "1 of 2 Updates failed" on "SubmitChanges()"

I am updating an object of type X and its children Y using LINQ to SQL and then submitting changes and getting this error
Example Code
X objX = _context.X.ToList().Where(x => x.DeletedOn == null).First();
objX.DeletedOn = DateTime.Now;
EntitySet<Y> objYs = objX.Ys;
Y objY = objYs[0];
objY.DeletedOn = DateTime.Now;
_context.SubmitChanges();
On SubmitChanges() I get an exception "1 of 2 Updates failed", no other information as to why that happened. Any ideas?
Also the exception type is
ChangeConflictException
Sooo what was the cause of the problem
- A trigger
I did a sql profiler and saw that
When ObjY's DeletedOn property got updated a trigger updated
ObjX's property (value in table) called CountOfX
which led to an error as the SQL created by LINQ to SQL had the old CountOfX value in it.
Hence the conflict.
If you ever get this error - SQL profiler is the best place to start your investigation
ALSO NOT RELATED TO THE QUESTION
I am testing LINQ to SQL and ADO.net Framework, weirdly this error happened in LINQ to SQL but not in ADO.net framework. But I like LINQ to SQL for its Lazy Loading. Waiting for EF to get outta beta
I'm not sure what the cause of the error may be exactly, but there seem to be a number of problems with the example you've provided.
Using ToList() before the Where() method would cause your context to read the entire table from the DB into memory, convert it to an array; and then in the same line you immediately call Where which will discard the rows you've loaded, but don't need. Why not just:
_context.X.Where(...
The Where method will return multiple items, but the second line in the example doesn't appear to be iterating through each item individually. It appears to be setting the DeletedOn property for the collection itself, but the collection wouldn't have such a property. It should fail right there.
You are using DateTime.Now twice in the code. Not a problem, except that this will produce ever so slightly different date values each time it is called. You should call DateTime.Now once and assign the result to a variable so that everything you use it on gets identical values.
At the point where you have "Y objY = objYs[0]" it will fail if there are no items in the Y collection for any given X. You'd get an index out of bounds exception on the array.
So given this example, I'm not sure if anyone could speculate as to why code modeled after this example might be breaking.
In LINQ2SQL Data Context diagram select the Entity and the field where the count is stored. (A denormalized figure)
Now set the UpdateCheck = Never.
I had this kind of issue. I was debugging running single lines at a time. It turned out another process was modifying this record.
My manual debugging process was slowing down the normal speed of the function. When I ran it all the way to a line after the SubmitChanges method, it succeeded.
My scenario would be less common, but the nature of this error relates to the record becoming superceded by another function/process. In my case it was another process.

No results returned to a reader but the same query works thru SQL Management Studio

I'm experiencing weird behavior with some of full text search queries, especially those with multiple words. These are working fine when executed thru Management Studio but returning no results when called from a code. I did a SQL Trace to see what commands are being sent from my app and exactly same command come with results when executed from Management Studio but come with no results when called from my app using ExecuteReader method.
This call:
exec dbo.FullTextSearch_Articles #ftsQuery=N' FORMSOF (INFLECTIONAL, moravec) '
will return data for both my app and Management Studio while this command:
exec dbo.FullTextSearch_Articles #ftsQuery=N'( FORMSOF (INFLECTIONAL, jan) AND FORMSOF (INFLECTIONAL, moravec) )'
will only return data when executed from Management Studio. I copy/pasted these queries directly from a trace log.
On a code side, I'm using Enterprise Library, but overall my DB call is really simple:
using (var dataReader = (SqlDataReader)db.ExecuteReader(cmd))
{
if (dataReader.HasRows)
{
var results = new List<IFullTextSearchItem>();
while (dataReader.Read())
{
results.Add(CreateArticleSearchFromReader(dataReader));
}
return results;
}
return null;
}
In the second case, dataReader.HasRows is false for some reason, but again, when those queries are executed from a Management Studio, both returns some data.
I thought it might be due to a number of rows returned (second query returns much bigger set of results) but then sucessfully tested single word search with even more rows returned.
Any idea why DataReader would behave different from a simple Management Studio query execution would be appreciated.
Thanks,
Antonin
OK, this is interesting. I did a bit more debugging and found that dataReader.HasRows property is not accurate - for some reason this is set to false in some case even when there are data in Results View collection.
I wonder whether reader.HasRows is somehow dependable on the amount of data being transferred between client app and server - so in the case of lot of data, this property is not updated immediately once ExecuteReader method is called.
Anyway, simply by removing check for reader.HasRows solves this issue.

Categories