views:

432

answers:

3

I have tables with either many columns or a column with a large data set (XML doc), I need to load information from the table quickly (status info) into a class. I notices that Linq allows you to select columns as such...:

Using an anonymous type:

var query = (from name in some.Table
            select new { ColumnName = name.ColumnName });

MapEntToOb( query)
private void MapEntToObj( var query)          <------ doesn't work!

I want to call a routine to do stuff (mapping) using the query, but cannot pass it unlike the following...

LinqClass.Table query =  from name in some.Table
            select;

MapEntToObj( query)
...
private void MapEntToObj( LinqClass.Table query)

for now I'll move the mapping into local scope, but I would like to have a clean consistant design for all by data mapping.

+5  A: 

Unfortunately what you want to do is not possible. Under the hood, the query variable is typed to be an IEnumerable of an anonymous type. Anonymous type names cannot be represented in user code hence there is no way to make them an input parameter to a function.

You're best bet is to create a type and use that as the return from the query and then pass it into the function. For example,

struct Data {
  public string ColumnName; 
}

var query = (from name in some.Table
            select new Data { ColumnName = name });
MethodOp(query);
...
MethodOp(IEnumerable<Data> enumerable);

In this case though, you are only selecting a single field, so it may be easier to just select the field directly. This will cause the query to be typed as an IEnumerable of the field type. In this case, column name.

var query = (from name in some.Table select name);  // IEnumerable<string>
JaredPar
My example was one, but most of the time it's more. Your answer through works (and quite obvious now). I just needed a break for lunch to think it though ;-)
tdrake
+2  A: 

Normally, you do this with generics, for example:

MapEntToObj<T>(IQueryable<T> query) {...}

The compiler should then infer the T when you call MapEntToObj(query). Not quite sure what you want to do inside the method, so I can't tell whether this is useful... the problem is that inside MapEntToObj you still can't name the T - you can either:

  • call other generic methods with T
  • use reflection on T to do things

but other than that, it is quite hard to manipulate anonymous types - not least because they are immutable ;-p

Another trick (when extracting data) is to also pass a selector - i.e. something like:

Foo<TSource, TValue>(IEnumerable<TSource> source,
        Func<TSource,string> name) {
    foreach(TSource item in source) Console.WriteLine(name(item));
}
...
Foo(query, x=>x.Title);
Marc Gravell
A: 

I've seen (and somewhat ashamed to say, done) a hack to be able to pass an anonymous type from a query to a method.

It's called "casting by example".

Here's an article that came up when I googled "casting by example c#"

http://tomasp.net/articles/cannot-return-anonymous-type-from-method.aspx

It might get the job done in a tight stop, but I wasn't too proud of it.

Roly
edit: forgot the link
Roly