Ok, I have managed to get the following working
public IQueryable getTicketInformation(int ticketID)
{
var ticketDetails = from tickets in _context.tickets
join file in _context.file_objects on tickets.ticket_id equals file.source_id
where tickets.ticket_id == ticketID
select new { tickets.ticket_id, tickets.title, tickets.care_of_email, file.filename };
return ticketDetails.AsQueryable();
}
I went ahead and created my own class (myObject) containing the primitives ticket_id, title, care_of_email and filename. Which are the items I am returning in my linq statement.
I modified my statement to be
public IQueryable<myObject> getTicketInformation(int ticketID)
{
var ticketDetails = from tickets in _context.tickets
join file in _context.file_objects on tickets.ticket_id equals file.source_id
where tickets.ticket_id == ticketID
select new { tickets.ticket_id, tickets.title, tickets.care_of_email, file.filename };
return ticketDetails.AsQueryable()<myObject>;
}
thinking that this would make it type safe with generics, but I get the error "Cannot convert method group 'AsQueryable' to non-delegate type 'System.Linq.IQueryable'. Did you intend to invoke the method?"
Is what I am trying to do even possible?
Does the myObject class need to implement IEnumerable or IQueryable?
Or is it best to construct the object MyObject from the linq resultset and then just return from the function the object MyObject
public myObject getTicketInformation(int ticketID)
{
....linq statement....
myObject o = null;
foreach (obj in linqstatemt)
{
o = new myObject();
o.ticket_id = obj.ticket_id
.......
}
return o;
}
This line is syntactically incorrect:
and should read
Also, you're creating anonymous objects with the
select new {
, but you want to createmyObject
instances. A correct implementation would look like this:The
new SomeClass() { Property = value, ...
syntax creates aSomeClass
instance and sets the properties to the given values. Alternatively you could implement a constructor on themyObject
class and call it in the linq statement withselect new myObject(...)
.As Marc stated you're not constructing instances of
myObject
when your query is run. But additionally you don't need to cast it to anIQueryable<T>
, a LINQ select statment will return anIQueryable<T>
unless explicity cast to anIEnumerable<T>
.Also, be careful that your DataContext hasn't been disposed of before you try and access the data being returned. But I noticed your context is not constructed in the method, be careful that you're not maintaining a DataContext for too long, it's a unit-of-work object and not meant to be kept open for long periods of time.
Gents, It all makes sense as long as you're only returning single table, but what if there's two or more to be returned???
You mean:
(note I tweaked the names slightly to be more C#-idiomatic)
This is an "object initializer" that creates a new
MyObject
(per record) and assigns the properties from the source data. What you had was an "anonymous type" initializer, which isn't the same. Note that if you have a non-default constructor, you could also use something like:which uses the specified constructor, passing in the supplied values from the source data.
This will then be
IQueryable<MyObject>
; you don't need to call.AsQueryable()
. Note it would be better for your function to return the typed form (IQueryable<MyObject>
) than the untypedIQueryable
.