Hello,
I'm trying to figure out if I'm going to use LINQ on a new project and I've
got a dumb question. I ran sqlmetal against my database to generate the
classes I need. I setup a class (like an "entity access layer" class) to run
the actual queries. So I've got a method that returns a list of contacts:
public static IEnumerable<Contact> GetContacts
I've got a datagrid where I want to display the contacts, but I need to join
the contacts with another table (OtherData, for example). How can I do a join
and then return all of the data back from this method? Would I need to create
a class that contains all of the fields from the contacts and otherdata
classes (so I could have a method like below)?
public static IEnumerable<ContactsWithOtherData> GetContactsWithOtherData
I hope I'm making sense. Thanks for any help, I really appreciate it.
Thanks,
Nick
Nicholas Paldino [.NET/C# MVP] - 23 Jan 2008 03:12 GMT
Nick,
Yes, if you want to flatten the data into one "table" (by that, I mean a
type which has the attributes for both the parent and the child), you need
to create a new type, and use a join operation to perform your select into
the new type.

Signature
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com
> Hello,
>
[quoted text clipped - 22 lines]
> Thanks,
> Nick
Nick - 23 Jan 2008 16:49 GMT
Thanks for your help. Pardon my ignorance again, but if I setup my class and
I want to use LINQ to do the query, how do I cast what is returned to my new
class (or what would be the preferred method for this)? This is what I have
in a method:
var q =
from c in db.Contacts
from od in c.OtherData
where od.someid=x
select new { c, od };
return q;
How do I cast q as a ContactOtherData type?
Thanks again for your help, I really appreciate it.
Nick
Jon Skeet [C# MVP] - 23 Jan 2008 17:47 GMT
> Thanks for your help. Pardon my ignorance again, but if I setup my class and
> I want to use LINQ to do the query, how do I cast what is returned to my new
[quoted text clipped - 12 lines]
>
> Thanks again for your help, I really appreciate it.
q isn't a ContactOtherData type unless you've got some interesting
logic somewhere. It's more likely to be IEnumerable<SomeType> or
IQueryable<SomeType> where SomeType is an anonymous type consisting of
the contact and the other data. Hover over "var" to see the actual type
of q.

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Nick - 23 Jan 2008 19:23 GMT
Jon,
Thanks for your help. You're right about q, it's an anonymous type (I don't
have any interesting logic). I haven't dealt much with anonymous types. Is it
possible to cast it to the ContractOtherData type?
Thanks,
Nick
Jon Skeet [C# MVP] - 23 Jan 2008 19:34 GMT
> Thanks for your help. You're right about q, it's an anonymous type (I don't
> have any interesting logic).
Are you sure it isn't an IEnumerable<some anonymous type>? That's what
I'd expect it to be.
> I haven't dealt much with anonymous types. Is it
> possible to cast it to the ContactOtherData type?
No - but if you want to use a particular type, put that in the
"select" clause instead of using an anonymous type there. For instance:
var q =
from c in db.Contacts
from od in c.OtherData
where od.someid=x
select new ContactOtherData (c, od);
(assuming you've got a ContactOtherData constructor taking a Contact
parameter and an OtherData parameter).

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Nick - 23 Jan 2008 20:29 GMT
Ahh, now the light bulb comes on. Thanks for your help, I really appreciate it.
> > Thanks for your help. You're right about q, it's an anonymous type (I don't
> > have any interesting logic).
[quoted text clipped - 16 lines]
> (assuming you've got a ContactOtherData constructor taking a Contact
> parameter and an OtherData parameter).
Jon Skeet [C# MVP] - 23 Jan 2008 20:37 GMT
> Ahh, now the light bulb comes on. Thanks for your help, I really appreciate it.
No problem. With all the new syntax in C# 3, it's easy to follow a
pattern but not really understand all the different bits. Once you pick
it apart, it gradually makes sense :)

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Marc Gravell - 23 Jan 2008 06:48 GMT
> public static IEnumerable<Contact> GetContacts
> public static IEnumerable<ContactsWithOtherData> GetContactsWithOtherData
Minor thing - but you might want to make the IQueryable<Contract> etc
so that it is composable - i.e. if you do use GetContacts() in a
further query (even if just to order it, or take the first page, or
apply an additional "where" filter), then the combined query happens
at the database. Of course, this only applies if using direct SELECT;
if you are using SPs it can't inject into the middle.
Marc