0

I'm trying to get data for a gridview and have a cast error.

In the code below, if I just return "myuserlist" - all is good. As soon as I try to select only 2 fields (as in this code), I get the casting error. I've looked at other comments posted here regarding this problem and tried a number of things with no success.

Imports System.Linq
Imports RoutesEntities

Partial Class ProfileTest
    Inherits System.Web.UI.Page
    Private myentity As New RoutesEntities()

    Public Function GridView1_GetData() As IQueryable(Of AllUser)
        Return From myuserlist In myentity.AllUsers Select New With {myuserlist.UserName,myuserlist.Email}
    End Function

Error:

System.InvalidCastException was unhandled by user code
HResult=-2147467262
Message=Unable to cast object of type 'System.Data.Entity.Infrastructure.DbQuery`1[VB$AnonymousType_0`2[System.String,System.String]]' to type 'System.Linq.IQueryable`1[AllUser]'.
Source=App_Web_oelfrca5
StackTrace:
   at ProfileTest.GridView1_GetData() in C:\xxx\yyy\zzz\Profile.aspx.vb:line 10
InnerException: 

I tried this (among other things):

Return From myuserlist In myentity.AllUsers Select New AllUser() With {
               .UserName = myuserlist.UserName,
               .Email = myuserlist.Email}

and got this:

Exception Details: System.NotSupportedException: The entity or complex type 'RoutesModel.AllUser' cannot be constructed in a LINQ to Entities query.
Zev Spitz
  • 13,950
  • 6
  • 64
  • 136
Bicycle Dave
  • 484
  • 1
  • 7
  • 25
  • Although it is a post (and a good answer) for C#, this applies also for VB.NET: http://stackoverflow.com/questions/5325797/the-entity-cannot-be-constructed-in-a-linq-to-entities-query – Styxxy Nov 24 '13 at 19:59

1 Answers1

0

If you don't need the specific AllUser type at compile-time, you can have your function return an IQueryable(Of Object), or perhaps even a simple IQueryable:

Public Function GridView1_GetData() As IQueryable
    Return From myuserlist In myentity.AllUsers Select New With {myuserlist.UserName,myuserlist.Email}
End Function

Update Return IQueryable(Of Object) if you'll need LINQ on the results:

Sub DataTest()
    Dim qry = GridView1_GetData
    Dim filteredQry = qry.Take(5)
End Sub
It is easier to do this with VB.NET than in C#, because VB.NET supports late binding -- even though the variable `x` is of type `Object`, and thus may not have a `UserName` property, the compiler will allow `UserName` to be resolved at runtime.

This is not as useful as it might be, because you can't pass an expression into the LINQ operator, e.g. you can use .Take or one overload of .Any, but not .Where.

Zev Spitz
  • 13,950
  • 6
  • 64
  • 136
  • Thank you very much! I tried for a couple of hours with all the other C# suggestions (trying to convert to VB) with utter failure. Your code worked out-of-the-box. However, could you shed a little light on why wouldn't I just use IQuerable all the time and never use IQueryable(Of xxxx). Your method works also for returning the entire "myuserlist" with no sub-list. Am I giving up something? And thanks again! – Bicycle Dave Nov 25 '13 at 00:50
  • @user2923427 Updated. What do you mean by a sub-list? – Zev Spitz Nov 25 '13 at 09:38
  • Sorry for poor terminology - I just meant this works also: Return From myuserlist In myentity.AllUsers Select myuserlist – Bicycle Dave Nov 25 '13 at 15:06
  • @user2923427 When using `Select` you are defining a **projection** -- each element should be projected into a new element. (The new element can be a different type -- in the first example, each `AllUser` is being projected to an anonymously typed object (with `UserName` and `Email` string properties)). However, there is no point in projecting each element to itself; you can just write `Return myentity.AllUsers.AsQueryable`. – Zev Spitz Nov 25 '13 at 15:34
  • Thanks Zev. If I can pursue a bit more the line: "Dim filteredQry = qry.Where(Function(x) x.UserName.StartsWith("a")).Take(5)" I can't get this work even reduced to: Dim filteredQry = qry.Where(Function(x) x.UserName) - I keep getting this error in the editor "late binding objects can't be converted to an expression tree" I can see where this general idea is useful but I just can't get it to get beyond this syntax error. – Bicycle Dave Nov 25 '13 at 18:22
  • @user2923427 My mistake -- even though in general you can use variables of Object this way, you can't do it within an expression, which is what many of the LINQ methods on `IQueryable` expect. – Zev Spitz Nov 26 '13 at 12:15