问题
Goal/Problem: I am trying to use the First or FirstOrDefault to only return 1 result from the Database. I'm getting the following error:
Cannot implicitly convert type 'Program.Data.view' to System.Linq.Iqueryable An explicit conversion exists (are you missing a cast)
What I've tried: After looking through documentation and many SO articles, I tried different ways of casting, including the code below. Articles such as Cannot implicitly convert type 'System.Linq.IQueryable<>to . An explicit conversion exists (are you missing a cast?). Most of the articles are going from System.Linq.IQueryable<> to something else, not this direction. Either way casting should be relatively easy, what am I missing?:
IQueryable<Program.Data.view> someVariable = db.view.First(m => m.ID == Search_ID);
My method signature is:
public IQueryable<Program.Data.view> GetDataFromQuery()
回答1:
First()
and similar methods (like FirstOrDefault()
or Count()
or Average()
) does not return an IQueryable<Program.Data.view>
and does not use deferred execution.
First()
is executed immediatly and returns only one (well, the first) Program.Data.view
.
So the error message is correct. Change your signature to
public Program.Data.view GetDataFromQuery()
and the mentioned line to:
Program.Data.view someVariable = db.view.First(m => m.ID == Search_ID);
回答2:
When you use of method like: First()
, FirstOrDefault()
, Single()
, SingleOrDefault()
, Count()
and something like this, return type of data that you mapped in Entity-Framework
.
When you work with Entity-Framework
, Do you know, when EF
get data from database
?
Look this sample:
var result = context.Student.Where(x=>x.Id == model.Id);
In this sample, the result type is IQueryable<T>
and didn't call database, this is just a query.
Now look this sample:
var result = context.Student.Where(x=>x.Id == model.Id).ToList();
In this sample, the result type is T
and called database and we have data about Student
Table.
Attention that ToList()
Or ToListAsync()
method always call database and execute the query.
回答3:
If you can not change signature of your GetDataFromQuery
or you would like to save deferred execution, you can use this approach:
db.view.Where(m => m.ID == Search_ID).Take(1);
Please note that this replacement is not strictly equivalent: it will not throw even if db.view
has no data
回答4:
What ended up working was the following:
var someVariable = db.view.Where(m => m.Some_ID == Search_SomeID).GroupBy(x => x.Some_ID).Select(g => g.OrderByDescending(p => p.Column_Two).FirstOrDefault()).AsQueryable().OrderBy(x => x.Column_Three);
AKA (format):
Where().GroupBy().Select(...OrderByDescending().FirstOrDefault()).AsQueryable().OrderBy();
Not sure why the others gave me errors but doing it in this order worked Also, the OrderBy at the very end seems completely unecessary by logic, but I get a System.NotSupportedException error when I don't have it (The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip' ... this happens on .DataBind())
来源:https://stackoverflow.com/questions/52558818/cannot-implicitly-convert-type-program-data-view-to-system-linq-iqueryablepro