IOrderedQueryable- Specified cast is not valid - c#

I am getting a InvalidCast exception when I try to iterate through an IOrderedQueryable object as below.
appreciate any help:
IOrderedQueryable<Result> rs =
from res in db.Results
orderby res.Id
select res;
if (rs != null)
{
IEnumerator<Result> enumerator = rs.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
Result r = enumerator.Current;
Console.WriteLine(r.BugId);
}
}
}
Run-time error:
System.InvalidCastException was unhandled
HResult=-2147467262
Message=Specified cast is not valid.
Source=System.Data
StackTrace:
at System.Data.SqlClient.SqlBuffer.get_Int32()
at System.Data.SqlClient.SqlDataReader.GetInt32(Int32 i)
at Read_Result(ObjectMaterializer`1 )
at System.Data.Linq.SqlClient.ObjectReaderCompiler.ObjectReader`2.MoveNext()

Seems that inside your Results table you have column that is supposed to be an Int32 on DBContext level but some of values that are inside it cannot be casted to Int32. Make sure that your DBContext matches table definition. Maybe you forgot to update it after some table schema changes...

The problem seems to be in the r.BugId part.
The code of Result seems to indicate it is an int, but the returned value from the database isn't (maybe it is null?). Hence, you receive this error message.
Check if BugId is indeed an integer in the database, if not, and Result is generated though code, try to regenerate.

Related

return in if statement throws conversion error

I will apologize in advance for the long post. Just trying to give you all the information I have.
I have an if statement in a method that looks like this:
var comparison = await SystemService.SearchCount();
var fileExporter = Configure();
var fileName = "SearchResults"
if (defaultValue <= comparison)
{
var result = SearchResult.Rows.Where(s => VSR.Any(s2 => s2.ID == s.Values.FirstOrDefault()));
var records = SearchResult.Rows.ToList();
await Task.Yield();
return fileExport.ToCsv(records, fileName);
}
The error that I am getting is the following error:
cannot convert from 'System.Collections.Generic.List<SearchRows>' to 'System.Collections.Generic.IList<SearchResults>'
I tried to change the return to explicitly cast to IList like this:
return fileExport.ToCsv((IList<SearchResults>)records, fileName);
This will let it build in Visual Studio but it throws an InvalidCastException when I run it and look at the developer tools:
System.InvalidCastException: Unable to cast object of type 'System.Collections.Generic.List[SearchRow] to type System.Collections.Generic.IList[SearchResult].
What am I missing here? I don't see an issue at all with the code.
The SearchResults model is a listing of the records to be returned (Id, name etc)
The SearchRows model serves as a wrapper for the columns and rows (I didn't name these they came in with the legacy code)
records is of type List<SearchRow>, which is not compatible with the type List<SearchResult>, you either have to convert the SearchRows to SearchResults (e.g. via a Select) or alter the type accepted by ToCSV

Unable to cast object of type 'System.Int32' to type 'System.String' in LINQ query

Hi I'm trying to remove a user from my database. I'm not sure why I'm receiving this error though since none of my variables (employeeName, departmentName) are of type int.
The debugger keeps stopping at this block of code with the "Unable to cast object of type 'System.Int32' to type 'System.String'." error.
//Note: employeeName type is navchar
var empQuery =
from dep in db.Department
join emp in db.EmployeeDetails
on dep.departmentId equals emp.departmentId
where dep.departmentName == reqDep
&& emp.employeeName == reqUser
select emp;
//Debugger keeps pointing to the foreach with the error
foreach (var element in empQuery)
{
Console.WriteLine("user: " + element + " has been deleted");
db.EmployeeDetails.DeleteOnSubmit(element);
}
// Freeze the console window.
Console.ReadLine();
If it helps, I've included the entire code below.
namespace runLinqSql
{
// Table<T> abstracts database details per table/data type.
[Database]
public class FireEvacuation : DataContext
{
public Table<Employee> EmployeeDetails;
public Table<EmpDepartment> Department;
public FireEvacuation(string connection) : base(connection) { }
}
class Program
{
static void Main(string[] args)
{
// Use a connection string.
FireEvacuation db = new FireEvacuation
(#"C:\Program Files\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQL\DATA\runSqlLinq\FireEvacuation.mdf");
////specify department to be removed
string reqDep = "KOM";
// Attach the log to show generated SQL.
db.Log = Console.Out;
////specify user to be removed
string reqUser = "Jason";
//Note: employeeName type is navchar
var empQuery =
from dep in db.Department
join emp in db.EmployeeDetails
on dep.departmentId equals emp.departmentId
where dep.departmentName == reqDep
&& emp.employeeName == reqUser
select emp;
//Debugger keeps pointing to the foreach with the error
foreach (var element in empQuery)
{
Console.WriteLine("user: " + element + " has been deleted");
db.EmployeeDetails.DeleteOnSubmit(element);
}
// Freeze the console window.
Console.ReadLine();
try
{
db.SubmitChanges();
}
catch (Exception e)
{
Console.WriteLine(e);
// Provide for exceptions.
}
One method to find problems like this:
(I call this hard-core-debugging)
Make your code smaller
Remove one element after the other form the piece of code which causes the problem.
Run the code after each modification.
This way you find out, which element causes the problem.
In your case, you could replace the query with a very simple one, then add the join and so forth.
Seems to me that the error has something to do with one of the following lines:
on dep.departmentId equals emp.departmentId
where dep.departmentName == reqDep
&& emp.employeeName == reqUser
(The reason the exception is being thrown at the loop, is that the expression will not have been run before that, which is the first time it is needed).
You are comparing values in pairs here. Now if one of the values in a pair is of type string, and the other is of type int, that will cause that error.
To fix this, double check that each pair you are comparing are really valid (i.e. that dep.departmentId and emp.departmentId are really what you want to compare), and that the types are the same.
If the types are not the same, but they can still be expected re return equivalent values (example: dep.departmentId could be an int value of 123, while emp.departmentId is the string "123"), you can probably compare them both as strings:
on dep.departmentId.ToString() equals emp.departmentId.ToString()
I found that the problem here wasn't with my actual LINQ query in my code but instead a problem with the table that I was querying in my dbml file. The problem was the primary key of the table i.e. it had none! Once I set the primary key of the table and then added it again to my dbml file, my query worked.

System.InvalidCastException: Specified cast is not valid. Error

I am on a C# ASP.NET project.
I have a MySQL table with a userid field of type int.
Now I want to get the number of rows where value of userid equals certain value using LINQ.
To achieve this, I wrote the following method:
public int getCount(int usercode) {
int count = 0;
DataTable mytable = getAllRowsAndReturnAsDataTable(); // assigning a DataTable value to mytable.
if (mytable.Rows.Count > 0) {
count = (from x in mytable.AsEnumerable() where x.Field<Int32>("userid") == usercode select x).Count();
}
return count;
}
but it is showing error System.InvalidCastException: Specified cast is not valid. showing count = (from x in mytable.AsEnumerable() where x.Field<Int32>("userid") == usercode select x).Count(); in red highlight area.
I don't know what I did wrong here. Please help.
The most likely cause of the InvalidCastException is the x.Field<Int32>("userid") line. The Field<T> extension method will throw an InvalidCastException in the case where the actual type of the data doesn't match the type which was passed to Field<T>. Hence if userid wasn't an Int32 this would throw.
EDIT
Based on your comments the type of userid is actually UInt32 and not Int32. This is what is causing the problem. Try using the following and it should work
x.Field<UInt32>("userid")
Without looking at the data coming back from your database I can only guess that the following part of your LINQ is at fault:
x.Field<Int32>("userid")
Your userid column value probably isn't an int, I would put my money on it being NULL?
UPDATE: Can you confirm it's not the Field call that is breaking? Simply change your code to something like this without the Field call:
public int getCount(int usercode){
int count = 0;
DataTable mytable = getAllRowsAndReturnAsDataTable(); // assigning a DataTable value to mytable.
if (mytable.Rows.Count > 0) {
count = mytable.AsEnumerable().Count(); // No WHERE function call so no casting.
}
return count;
}
You could also inspect what the values are that are returned by mytable.AsEnumerable() in a watch window for example to ensure that everything looks correct. If the code above works then it's the Field call blowing up. Find out which row cannot be cast to an Int32 and go from there.
If it is in fact NULL, there are a number of ways you can solve this.
Make sure you don't return NULL from your database query, in MySQL you can use IFNULL.
Use a nullable type for the generic being passed into Field:
where x.Field("userid") == (Int32?)usercode

"Invalid attempt to read when no data is present" when starting a foreach loop on query result

I have this query:
// _db derives from DbContext
var toProcess = from jobItem in _db.Jobs
where jobItem.State == desiredState
select jobItem.ItemId;
foreach (Guid itemId in toProcess ) //exception thrown on this line
{
// whatever
}
which most of the times runs fine, but once in a while the line with foreach will throw:
System.InvalidOperationException: Invalid attempt to read when no data is present
with the following stack trace:
System.Data.SqlClient.SqlDataReader.ReadColumnHeader(Int32 i)
System.Data.SqlClient.SqlDataReader.IsDBNull(Int32 i)
System.Data.Common.Internal.Materialization.Shaper.ErrorHandlingValueReader`1.GetValue(DbDataReader reader, Int32 ordinal)
System.Data.Common.Internal.Materialization.Shaper.GetColumnValueWithErrorHandling[TColumn](Int32 ordinal)
System.Data.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper)
System.Data.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext()
which doesn't make any sense. How do I resolve this?
As per your response to my comment:
There's some medium weight activity that is expected to be done within
several seconds but I guess it can take longer. Do you think a timeout
happens?
I imagine that it's a timeout or something similar. You could increase the timeout, or you could just force it to evaluate and be stored in memory for later processing. You can do this by adding ToArray() at the end of the query:
var toProcess = (from jobItem in _db.Jobs
where jobItem.State == desiredState
select jobItem.ItemId).ToArray();
See if that helps.

Specified cast is invalid error, LINQ to Oracle table

Oracle column: user_id int not null,
Linq query:
UserId = user.Field<int>("user_id"),
UserId is int type. Other string, char fields are workign fine, only when I use thsi field I get this error.
What is the correct mapping or anythign I am doing wrong ?
If you're using Field<T>() then that suggests you're using a DataTable, at which point the database type is mostly irrelevant. The exception should show you how the cast has failed - what the actual type is. If it doesn't, you can easily put some diagnostics in though:
object o = user["user_id"];
if (o == null)
{
Console.WriteLine("user_id is null");
}
else
{
Console.WriteLine("Actual type of user_id: {0}", o.GetType());
}
I suspect you'll find it's long or short, or something like that - but this should show you for sure.

Categories

Resources