Error: Cast System.Data.Objects.ObjectQuery - asp.net-mvc

I'm trying to query my EF Model (using ASP.NET MVC WebApi) but only the first version (using SingleOrDefault) works and not the second one and i can't get my head around it!
Working:
Public Overloads Shared Function GetById(id As Integer) As MEDIA
Dim db As New EFEntities()
Dim r As New MEDIA()
r = db.MEDIA.SingleOrDefault(Function(p) p.id = id)
Return r
End Function
Not Working:
Error : Unable to cast object of type 'System.Data.Objects.ObjectQuery`1[Data.MEDIA]' to type 'Data.MEDIA'
Public Overloads Shared Function GetById(id As Integer) As MEDIA
Dim db As New EFEntities()
r = From media In db.MEDIA
Where media.id= id _
Select media
Return r
End Function
I would really appreciate it if somebody could show me how to get the second version running and explain what the problem is!

In your first example, the line:
r = db.MEDIA.SingleOrDefault(Function(p) p.id = id)
initializes a single MEDIA object.
In your second example, however, the line:
r = From media In db.MEDIA
Where media.id= id _
Select media
initializes a collection of MEDIA objects - incompatible types.
If you changed your return expression in your second example to:
Return r.SingleOrDefault()
and stick Dim in front of the initialization of r it'll work.

Related

Stored procedure returning dynamic columns in Entity Framework

I have a function calling a SQL Server stored procedure using Entity Framework 6.2.
The stored procedure returns a result set which has different number of columns on each call, and column names may vary on each call.
Function getListOfDocs() As JsonResult
Try
Using entities As PromatEntities = New PromatEntities()
Dim param(1) As SqlParameter
param(0) = New SqlParameter("#ProjID", SqlDbType.Int)
param(0).Value = vProjectId
Dim query = entities.Database.SqlQuery(Of "help required here")("sp_EIP_IPSSDocMaster_Get", param) // cannot handle this case as entity framework needs type
Dim lstDocs = query.ToList
End Using
Return Json(New With {lstDocs}, JsonRequestBehavior.AllowGet)
Catch ex As Exception
ClsCommon.ExceptionManager(ex)
Return Nothing
End Try
End Function
But Entity Framework doesn't allow anonymous types in database.SqlQuery. Can anyone suggest a way to solve the issue and get the anonymous type data to view?

LLBLGenProQuery Vs IQueryable

I am using LLBLGen Pro, MVC 3 and VB.NET. I am trying to return an object of Iqueryable but i am getting following exception
Unable to cast object of type 'SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery1[Mail.DAL.EntityClasses.TblCostCentreEntity]' to type 'System.Linq.IQueryable1[Mail.Model.CostCentre]'.
I am not sure whats the difference betweeen LLBLGenProQuery and IQueryable? How do i return an IQueryable object using LLBLGenPro? My code is as following:
Public Function GetAllCostCentres() As IQueryable(Of Model.CostCentre) Implements ICostCentreRepository.GetAllCostCentres
Mapper.CreateMap(Of TblCostCentreEntity, CostCentre)()
Dim metaData As New LinqMetaData
Dim q = From p In metaData.TblCostCentre _
Select Mapper.Map(Of IQueryable(Of CostCentre), TblCostCentreEntity)(p)
'Dim t As IQueryable(Of CostCentre) = Mapper.Map(Of CostCentre)(q)
'Select New CostCentre With {.Active = p.Active, .CostCentre = p.CostCentre, .CreatedBy = p.CreatedBy, .DateCreated = p.DateCreated, .DateLastModified = p.DateLastModified, .ModifiedBy = p.ModifiedBy, .CostCentreID = p.CostCentreId}
Return q
End Function
IQueryable
(http://llblgen.com/documentation/3.5/LLBLGen%20Pro%20RTF/hh_goto.htm#Using%20the%20generated%20code/Linq/gencode_linq_gettingstarted.htm#LinqMetaData)
It's a query that will make the compiler produce code which creates at runtime a tree of Expression instances, representing the entire query, in short an Expression tree. An Expression tree is not executable directly, it has to be interpreted to execute what is specified inside the Expression tree. This is what a Linq provider, like Linq to LLBLGen Pro, does: it accepts an Expression tree, translates it into elements it can understand, interprets these elements and produces an executable form of this query.
ILLBLGenProQuery
(http://llblgen.com/documentation/3.5/LLBLGen%20Pro%20RTF/hh_goto.htm#Using%20the%20generated%20code/Linq/gencode_linq_gettingstarted.htm#ILLBLGenProQuery)
An interface defined on the IQueryable elements produced by LinqMetaData. This interface allows you to execute the query by calling the Execute method. The advantage of this is that you can get the query result in its native container, e.g. an entity collection. Another advantage is that to obtain a list of the results, the provider doesn't have to traverse the results in full, and copy over the results in a List: the returned results are already in the container they're initially stored in.

Returning DbQuery to view that requires IEnumerable

The problem:
Exception Details: System.InvalidOperationException: The model item
passed into the dictionary is of type
'System.Data.Entity.Infrastructure.DbQuery`1[System.Int32]', but this
dictionary requires a model item of type 'migros.Models.State'.
What I'm trying to do
I need to pass the result of the following linq query to a View.
using (var db = new migros_mockEntities1())
{
var listOfIdeas = (from x in db.States select x.ID);
return View(listOfIdeas);
}
The View requires IEnumerable, but it seems I can't cast the result of the linq query to IEnumerable.
I'm using entity framework database first approach.
The problem is that you trying to return ObjectQuery from within the using block.
Try to materialize your object-set
var listOfIdeas = (from x in db.States select x.ID).ToList();
Also, dont forget, that dealing with context can be tricky.
In your case var listOfIdeas = (from x in db.States select x.ID) is just a query, that will run only when you'd begin to iterate over it. So, if context gets already disposed you'd get an exception, trying to use listOfIdeas.

Getting only what is needed with Entity Framework

With a plain connection to SQL Server, you can specify what columns to return in a simple SELECT statement.
With EF:
Dim who = context.Doctors.Find(3) ' Primary key is an integer
The above returns all data that entity has... BUT... I would only like to do what you can with SQL and get only what I need.
Doing this:
Dim who= (From d In contect.Doctors
Where d.Regeneration = 3
Select New Doctor With {.Actor = d.Actor}).Single
Gives me this error:
The entity or complex type XXXXX cannot be constructed in a LINQ to Entities query.
So... How do I return only selected data from only one entity?
Basically, I'm not sure why, but Linq can't create the complex type. It would work if you were creating a anonymous type like (sorry c# code)
var who = (from x in contect.Doctors
where x.Regeneration == 3
select new { Actor = x.Actor }).Single();
you can then go
var doctor = new Doctor() {
Actor = who.Actor
};
but it can't build it as a strongly typed or complex type like you're trying to do with
var who = (from x in contect.Doctors
where x.Regeneration == 3
select new Doctor { Actor = x.Actor }).Single();
also you may want to be careful with the use of single, if there is no doctor with the regeneration number or there are more than one it will throw a exception, singleordefault is safer but it will throw a exception if there is more than one match. First or Firstordefault are much better options First will throw a exception only if none exist and Firstordefault can handle pretty much anything
The best way to do this is by setting the wanted properties in ViewModel "or DTO if you're dealing with upper levels"
Then as your example the ViewModel will be:
public class DoctorViewModel{
public string Actor {get;set;}
// You can add as many properties as you want
}
then the query will be:
var who = (From d In contect.Doctors
Where d.Regeneration = 3
Select New DoctorViewModel {Actor = d.Actor}).Single();
Sorry i wrote the code with C# but i think the idea is clear :)
You can just simply do this:
Dim who= (From d In contect.Doctors
Where d.Regeneration = 3
Select d.Actor).Single
Try this
Dim who = contect.Doctors.SingleOrDefault(Function(d) d.Regeneration = 3).Actor

Why can't I get anything back when I use Linq to Sql Select?

Could you please check my code? Why can't I get any values back when I use Linq to Sql?
BHS_TimeSheet is my database table in which have some records.
Model.TimeSheet is a class I create in the model.
Private db As DataFactoryDataContext
Public Sub New()
db = New DataFactoryDataContext
End Sub
Public Sub New(ByVal repository As DataFactoryDataContext)
db = repository
End Sub
Public Function GetTimeSheetByProject(ByVal wbs1 As String, ByVal wbs2 As String, ByVal wbs3 As String) _
As List(Of Model.TimeSheet) Implements ITimeSheetRepository.GetTimeSheetByProject
Return (From ts In db.BHS_TimeSheets _
Where ts.WBS1.Equals(wbs1) And ts.WBS2.Equals(wbs2) And ts.WBS3.Equals(wbs3) _
Select New Model.TimeSheet(ts.TSBatchNo, ts.Employee, ts.TransDate, ts.WBS1, ts.WBS2, ts.WBS3, ts.LaborCode, _
ts.RegHrs, ts.OvtHrs, ts.SpecialOvtHrs, ts.TransComment, ts.Status, ts.AuthorizedBy, _
ts.RejectReason, ts.ModDate)).ToList
End Function
Your Linq-to-SQL statement
(From ts In db.BHS_TimeSheets
Where ts.WBS1.Equals(wbs1)
And ts.WBS2.Equals(wbs2)
And ts.WBS3.Equals(wbs3) _
basically corresponds to this SQL query:
SELECT * FROM dbo.BHS_TimeSheets
WHERE WBS1 = (value for wbs1)
AND WBS2 = (value for wbs2)
AND WBS3 = (value for wbs3)
Does that SQL query return any values, if you call it with in SQL Server Management Studio using the same parameters for wbs1, wbs2, wbs3 as you do in your Linq-to-SQL code??
Update: okay, so the SQL query does return results - next step: approach the Linq-to-SQL stuff step by step. First, try this - do you get any results??
Dim basicQueryResults = (From ts In db.BHS_TimeSheets
Where ts.WBS1.Equals(wbs1)
And ts.WBS2.Equals(wbs2)
And ts.WBS3.Equals(wbs3)
).ToList();
Does your resulting list of items have a .Count > 0 or not??
If not: there must be something wrong with your Linq-to-SQL model then. Have you changed your database and not updated the DBML file?? Can you drop the DBML file and do it again - does it work now? Or do you still have the same results??

Resources