views:

598

answers:

4

I'm new to LINQ, I've used LINQ to SQL to link to two tables, it does return data, which is cool. What I'm trying to understand is what datatype is being returned and how do I work with this datatype?

I'm used to dealing with datatables. Are we throwing out datatables (and all the other ADO.Net object like rows, datasets etc.) now if using LINQ? If so, what are we replacing that with and how can I use it to do everything I did before with datatables? Also--does it make sense to replace datables, was there a deficiency with them?

Here is some code:

protected IEnumerable<string> GetMarketCodes()
{
    LINQOmniDataContext db = new LINQOmniDataContext();

    var mcodes = from p in db.lkpMarketCodes 
                    orderby 0
                    select p;

    return (IEnumerable<string>) mcodes;
}

This code does currently return data (I can see it in debug), but errors at the "return" line, because apparently my datatype is not IEnumerables, which was my best guess. So, one thing I'd like to understand as well is what datatype is my data being put into and how to return it to the calling function.

+4  A: 

It is returning an IQueryable<lkpMarketCode>, assuming that that lkpMarketCode is the type of data in db.lkpMarketCodes. If you want the strings, you need to select p.SomeProperty;, not just select p;.

You shouldn't need to cast (since IQueryable<T> implements IEnumerable<T>); it should also tell you this if you hover on mcodes.

Marc Gravell
It only tells you if you hover over an mcodes following the initial declaration. Visual Studio, for some reason, doesn't seem to know the type at it's declaration, only afterwards.
Mystere Man
+3  A: 

It's returning an IQueryable object. How does your table look like? I'm guessing the error is because your lkpMarketCodes table is not just one string column. It's returning the whole table.

If you want to return just an IEnumerable of strings, you'll have to return something that looks like this (I'm sure the syntax is a bit off):

var mcodes = from p in db.lkpMarketCodes 
orderby 0
select new { p.StringColumnName };
ajma
That returns an enumerable of an anonymous type with a single string property - not an enumerable of strings.
Marc Gravell
+3  A: 

I find it more convenient to return List<>'s so I know what I'm dealing with. So your code would be:

protected List<string> GetMarketCodes()
{
    LINQOmniDataContext db = new LINQOmniDataContext();

    var mcodes = from p in db.lkpMarketCodes 
                    orderby 0
                    select p.SomeProperty;

    return mcodes.ToList();
}

Having said that, I've hardly used LINQ-to-SQL so there are probably better ways around..

Nick
That almost certainly won't compile... for the reasons already given
Marc Gravell
Good point Marc! How about now?
Nick
In retrospect I've decided that converting everything to List<>'s was missing the point of using Linq-to-SQL, and now find returning the actual query far more useful.. :)
Nick
A: 

LINQ returns IQueryable<type>'s. This is a superset of IEnumerable. The reason you are getting an error is that your query is not returning an IQueryable<string> it's returning an IQueryable<lkpMarketCodes>. lkpMarketCodes is most likely an object, which can be thought of as similar to a row of records.

LINQ is a Object-Relational mapper, it maps Columns and Rows to Fields and Objects.

You can do pretty much all the same things that you could in ADO, but it works with objects rather than generic rows, so it's more type safe.

In your example, i'm going to assume that lkpMarketCodes is a table, and that table consists of at least two fields, mcode and description.

If you want to return an IEnumerable<string> of mcode's, you would do something like this:

protected IEnumerable<string> GetMarketCodes()
{
    LINQOmniDataContext db = new LINQOmniDataContext();
    var mcodes = from p in db.lkpMarketCodes 
        orderby 0 
        select p.mcode;
    return mcodes;
}

This will return your IEnumerable<string> of codes. One trick you can use to find out types is to simply use the variable after its declaration, then hover your mouse over the variable name and a popup will tell you it's type.

That is, if you hover over the return mcodes, it will tell you the type, but it will not tell you the type if you hover over the var mcodes.

Mystere Man