SingleResult<myObject> .ToList or .Count throws an InvalidCastException - c#

I have a stored procedure GetTopRecords(). The sp returns the top 500 records.
I dragged the sp from the server explorer to the LinqtoSql designer surface.
I changed the return type to Record
In code I have:
var x = myDataContext.GetTopRecords();
var y = x.Count();
var z = x.ToList();
either one of the last two lines above throws an InvalidCastException
the type of x is
System.Data.Linq.SqlClient.SqlProvider.SingleResult<Record>
Why am I getting an exception? What am I doing wrong? Please help.

x is not a list, it is single element. As a single element you can't convert it to a list of more than one element or count how many elements it has.
As you say "I changed the return type to Record". Why did you do this?

Since this is L2S (Linq To SQL), I'm assuming it's using Lazy loading, which means that only when calling Count or ToList, which are of immediate execution, the query is performed.
That said, the problem should be related to what you are returning from the GetTopRecords method, which isn't compatible with the Record type.
You should use the L2S designer to check if the result of that method is correctly mapped to a Record data type. Meaning that Record should be a L2S mapped table and GetTopRecords should return data from that table.

Well,can you give details what GetTopRecords() .What it returns?do you need count of top records?
var x = i.ToList();
var y = x.Count();
then it will allowed,but when ever you use tolist() ToList iterates on the query and creates an instance of List<> initialized with all the results of the query.
which is same for count(),becuse count also need all records to perform counting.
the purpose of tolist is to prefilled data with result.

I think there there have been changes to the database schema since the linq to sql classes were generated. therefore there is a mismatch between the database table and the linq to Sql object representing it. therefore, the calls fail because the .NET cannot successfully cast from the db created object to the linq to sql object

I am not sure how I resolved this. But it is fixed now. If someone runs into this problem, please add a note here and I will look up my code and post the proper answer. While I thank the responders above, unfortunately, none of the answers above helped.

Related

LINQ to Entities chaining commands with differing results

My question is more general, but I have an example to help illustrate:
db.aTable.Where(x => x.Date < someDateInThePast).OrderByDescending(x => x.Date).First()
That gives me one item, which differs from the item returned by this command:
db.aTable.Where(x => x.Date < someDateInThePast).ToList().OrderByDescending(x => x.Date).First()
(note the "ToList()" in the middle).
From what I can see, what is actually happening in the 1st example is the OrderBy is completely disregarding the filtering that is done by the .Where(). It is ordering the entire aTable.
And the 2nd query is giving the actually correct item.
The .Date parameter is a DateTime type (on SQL side it is a 'datetime').
Is this behaviour to be expected from LINQ to Entities?
By adding .ToList() you actually change the context in which the data is processed.
Your first query is handled by your database completely and you only return the value from .First() to your Entity-Instance.
In the second one, you basically give the command to load up the conditioned aTable by giving him the command .ToList() and THEN order it, add the second condition and pick the first Date value from that already instanced table.
Microsoft states link that a CLR change might lead to unexpected results, which is what you are doing.
One way to know exactly what is happening would be that you execute your statement on your SQL Server directly:
Select Top(1) Date
From aTable
Where Date < someDateInThePast
order by Date desc
And then create a dbset for your data up to the point where the context changes:
Select *
From aTable
Where Date < someDateInThePast
order by Date desc
And then call it separately in your c# environment. Then check whether the results still differ.
Hope this helps!
I can't fully explain why it works like this but I have found that the inclusion of the First() is what is causing the issue. When I view the raw SQL that is generated by the LINQ there is no reference to 'Order By' in it. I can only assume the ordering happens on the client side. But, there is reference to take 'TOP (1)' in the SQL. Meaning, because the SQL server is only returning 1 result, the order by is happening on just 1 result and doesn't do anything useful.
If I change First() to ToList() then the ordering works as expected. This doesn't solve my issue but it explains the behaviour.

Linq: Method has no supported translation to SQL - but how to dump to memory?

I have a Linq query that reads from a SQL table and 1 of the fields it returns are from a custom function (in C#).
Something like:
var q = from my in MyTable
select new
{
ID = my.ID,
Amount = GetAmount(ID)
};
If I do a q.Dump() in LinqPad, it shows the results, which tells me that it runs the custom function without trying to send it to SQL.
Now I want to union this to another query, with:
var q1 = (from p in AnotherQuery.Union(q)...
and the I get the error that Method has no supported translation to SQL.
So, my logic tells me that I need to dump q in memory and then try to union to that. I've tried doing that with ToList() and creating a secondary query that populates itself from the List, but that leads to a long list of different errors. Am I on the right track, by trying to get q in memory and union on that, or are there better ways of doing this?
You can't use any custom functions in a LINQ query that gets translated - only the functions supported by the given LINQ provider. If you want your query to happen on the server, you need to stick with the supported functions (even if it sometimes means having to inline code that would otherwise be reused).
The difference between your two queries boils down to when (and where) the projection happens. In your first case, the data from MyTable is returned from the DB - in your sample, just the ID. Then, the projection happens on top of this - the GetAmount method is called in your application for each of ID.
On the other hand, there's no such way for this to happen in your second query, since you're not using GetAmount in the final projection.
You either need to replace the custom function with inlined query the provider understands, or refactor all your queries to use the supported functions in addition with whatever you need to do in-memory. There's no point in giving you any sample code, since it depends entirely on your actual query, and what you're really trying to query for.

How to get a correct result of binary string intersection in Entity to Linq query

I save my data in a binary-look string, "100010" ,for example. And I want to check whether it has same value in corresponding place with the other string "100000".
So I try to use "Intersection". In this Condition, the result of intersection will be "100000", and it could be seen as the item I need for my requirement. But how can I use this conception when I query a Entity to Linq statement?
Here is my thought:
var chemicals = db.ChemicalItem.Where(c => c.CategoryNumber.ToCharArray().Intersect(catekey.ToCharArray()).Count()>0);
"CategoryNumber" is my data, and "catekey" is the string for comparing. Both of them are binary-look string(cantain 6 chars). And if the count is not 0,they have '1's in the same index. And I can get the correct query.
Sadly, It didn't work. I always get DbExpressionBinding Error. Can somone tell me What's Wrong? Thanks.
PS:I'm not good at English and post the question here first time, sorry for my bad expression and thank for your reading.
LINQ to Entities is trying to create a SQL query out of your condition, but is not able to do it for the expression you specified.
One way to "fix" the problem would be to do the filtering in code instead of in SQL, but this will impact performance, because all of the records will be retrieved to the client and filtered there. This is how you could do it (notice the added ToList()):
var chemicals = db.ChemicalItem.ToList().Where(c => c.CategoryNumber.ToCharArray().Intersect(catekey.ToCharArray()).Count()>0);
A suggested way would be to do the filtering in SQL, but in this case you will need to write an equivalent stored procedure in SQL which will do the filtering and call that from your EF code. Still such filtering will not be very effective because SQL will not be able to use any indices and will always need to do a table scan.

Why is this data not being displayed in DataGridView

I am retrieving data from an Access database using CoolStorage, and can successfully populate a Team DataGridView by setting its DataSource as Team.List().
However, I want to use a LINQ query on the result set to return the number of users for each team. As this screenshot shows the result is being returned fine, however the DataGridView displays no data. If I switch the DataSource to be Team.List() it displays the teams without any problems (though obviously not the number of users).
Is there something I need to do in order to use the LINQ result as a DataSource? I can get round this by adding a property to my Team class, however I don't understand why I can't use the LINQ result.
You will need to materialize your datasource before it can be used.
Try changing
this.dgvTeams.DataSource = d;
to
this.dgvTeams.DataSource = d.ToList();
LINQ uses deferred execution. That is, you have built your LINQ query but it will not actually be evaluated to produce results unless you add a method or aggregate on the end of the query to force immediate evaulation, or you can enumerate the result.
Try using...
this.dgvTeams.DataSource = d.ToList();

LINQ to Entities: Query not working with certain parameter value

I have a very strange problem with a LINQ to Entities query with EF1.
I have a method with a simple query:
public DateTime GetLastSuccessfulRun(string job)
{
var entities = GetEntities();
var query = from jr in entities.JOBRUNS
where jr.JOB_NAME == job && jr.JOB_INFO == "SUCCESS"
orderby jr.JOB_END descending
select jr.JOB_END;
var result = query.ToList().FirstOrDefault();
return result.HasValue ? result.Value : default(DateTime);
}
The method GetEntities returns an instance of a class that is derived from System.Data.Objects.ObjectContext and has automatically been created by the EF designer when I imported the schema of the database.
The query worked just fine for the last 15 or 16 months. And it still runs fine on our test system. In the live system however, there is a strange problem: Depending on the value of the parameter job, it returns the correct results or an empty result set, although there is data it should return.
Anyone ever had a strange case like that? Any ideas what could be the problem?
Some more info:
The database we query against is a Oracle 10g, we are using an enhanced version of the OracleEFProvider v0.2a.
The SQl statement that is returned by ToTraceString works just fine when executed directly via SQL Developer, even with the same parameter that is causing the problem in the LINQ query.
The following also returns the correct result:
entities.JOBRUNS.ToList().Where(x => x.JOB_NAME == job && x.JOB_INFO == "SUCCESS").Count();
The difference here is the call to ToList on the table before applying the where clause. This means two things:
The data is in the database and it is correct.
The problem seems to be the query including the where clause when executed by the EF Provider.
What really stuns me is, that this is a live system and the problem occurred without any changes to the database or the program. One call to that method returned the correct result and the next call five minutes later returned the wrong result. And since then, it only returns the wrong results.
Any hints, suggestions, ideas etc. are welcome, never mind, how far-fetched they seem! Please post them as answers, so I can vote on them, just for the fact for reading my lengthy question and bothering thinking about that strange problem... ;-)
First of all remove ObjectContext caching. Object context internally uses UnitOfWork and IdentityMap patterns. This can have big impact on queries.

Categories

Resources