I need to run a stored procedure on SQL Server, using LINQ, and throw an exception if it returns any rows. The following code works, although the foreach loop does not communicate my intent well enough:
foreach (var badData in context.BadDataForDay(today))
{
throw new Exception("Bad data found");
}
I wanted to write something like IF EXISTS() in SQL, but with LINQ:
var badData = from p in context.BadDataForDay(today) select p;
if (badData.Any())
{
throw new Exception("Bad data found");
}
This code compiles but Any() blows up with the following message:
Specified cast is not valid
What am I missing? Is Any() the right method to use in this case?
Edit:
I debugged, and the code blows up before the stored procedure is called, at the following generated line:
return ((ISingleResult<BadDataResult>)(result.ReturnValue));
To get it to work, I did the following:
I added another stored procedure and dragged it to my context:
CREATE PROCEDURE dbo.BadDataExists
@AsOfDate DATETIME
AS
BEGIN ;
SET NOCOUNT ON ;
SELECT COUNT(*) AS Cnt
FROM SomeTable
WHERE SOME conditions ;
END ;
I used this code:
foreach (var badDataCount in
context.BadDataExists(asOfDate).Where(badDataCount => badDataCount.Cnt > 0))
{
Although it works now, I would really like to understand what I was missing.
I assume your
foreachcode would also blow up, ifcontext.BadDataForDay(today)would return any data…The code that translates the objects from the database into C# objects and returns them as an enumerable inside
BadDataForDayseems to be performing a cast that compiles fine but that blows up at runtime, because the object that should be casted has the wrong type.The reason why
Anyandforeachonly blow up when data is returned is simple: Without data, no cast will be performed.