How select subset of columns from IQueryable<Type>?

R

Ronald S. Cook

From my business tier (class) I get back an IQueryable<Pen> of data. Here
is my client code that works fine:

PenClass penClass = new PenClass();
IQueryable<Pen> pens = penClass.SelectPens();

However, I want to then select a subset of this data from within the client.
I tried this:

IQueryable<Pen> pensSubset = from p in pens select p.PenId, p.PenNumber;

... but it doesn't even compile.

Can anyone tell me the correct syntax?

Thanks.
 
M

Marc Scheuner

From my business tier (class) I get back an IQueryable said:
However, I want to then select a subset of this data from within the client.
I tried this:

IQueryable<Pen> pensSubset = from p in pens select p.PenId, p.PenNumber;

You're not getting back a subset of (fewer) pens than originally,
you're "projecting" the pens - e.g. your extracting two items of
informaiton (PenId and PenNumber) from the "pens", but you don't have
pens anymore - you have parts of pens (a thing made up of a PenId and
a PenNumber). What you're getting back from this query is not a
collection of objects of type "Pen", but a LINQ-generated anonymous
type - check this out:

var pensSubset = from p in pens select p.PenId, p.PenNumber;
Console.WriteLine(pensSubset[0].GetType().FullName);

What does the type name say?? I'm sure it's no "pen" !


What you really need to do is create a query that selects "whole"
pens, but restricts their number by a where clause, something like

IQueryable<Pen> pensSubset =
from p in pens where p.PenId > 10 select p;

That way, you get all (complete) pen objects back ("select p") which
have an PenId larger than 10.

Marc
 
J

Jon Skeet [C# MVP]

Marc Scheuner said:
You're not getting back a subset of (fewer) pens than originally,

To be fair, the OP didn't say he wanted to get back a subset of the
rows, just a subset of the data. A projection would do exactly that.
you're "projecting" the pens - e.g. your extracting two items of
informaiton (PenId and PenNumber) from the "pens", but you don't have
pens anymore - you have parts of pens (a thing made up of a PenId and
a PenNumber). What you're getting back from this query is not a
collection of objects of type "Pen", but a LINQ-generated anonymous
type - check this out:

var pensSubset = from p in pens select p.PenId, p.PenNumber;
Console.WriteLine(pensSubset[0].GetType().FullName);

A crucial bit of syntax is missing here - the anonymous type
initializer:

var pensSubset = from p in pens select new { p.PenId, p.PenNumber };

Mind you, I usually find that when I'm *just* doing a projection (or
just doing a filter, etc - just one operation) it's simpler to call the
extension method directly:

var pensSubset = pens.Select(pen => new { p.PenId, p.PenNumber });
 
M

mesut

Ok. but what if I want to return PensSubset in a function?
I mean I call the class it returns PensSubset, how and what type do I
define in my function.

Public xxxType function1 (parm1, parm2){

//I don't want to return whe whole P set. just those to items of P.
return PensSubset
}

what should be iso xxxType???
 
J

Jon Skeet [C# MVP]

mesut said:
Ok. but what if I want to return PensSubset in a function?
I mean I call the class it returns PensSubset, how and what type do I
define in my function.

In that case you'd need to create your own class which roughly mirrored
the anonymous type generated for you with the new { ... } syntax. It
should have a constructor taking all the values you want from the full
row.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top