views:

79

answers:

2

I'm trying to inject some inline work as a Statement Lambda into a LINQ query select like so...

// NOTE: mcontext.Gettype() == System.Data.Linq.DataContext

// Okay - compiles, nothing unusual
var qPeople1 = from ME.tblPeople person in mcontext.tblPeoples
              select person;

// ERROR - see below compile Error - Can I retrofit this thing?
var qPeople2 = from ME.tblPeople person in mcontext.tblPeoples
               select (() => { 
                   return person; 
               })();

Error:

Error 2 Method name expected file.cs 166 27 MigrationCore

... however I'd also be equally happy to see an Expression Lambda work inline first.

Note: I know the code sample is redundant in its effort but I'm looking for the basic concept. If it's workable I will be expanding it.

+5  A: 

Query syntax requires a method reference - it won't accept a lambda and in your second example you're giving it a ME.tblPeople instance.

However, if you use the extension method syntax you can achieve this easily:

int i = 0;
var qPeople3 = (from ME.tblPeople person in mcontext.tblPeoples
                select person).Select(person => { i += 1; return person; });

(I've added the incrementing integer as an example, though note that it doesn't actually change from zero until you've enumerated qPeople3.)

Addendum

This only works with LINQ to Objects. To use it with a LINQ to SQL query an AsEnumerable() call is required before the Select() call.

Notes

You don't actually need the from-in-select construct for this example, the snippets below are (AFAICT) identical, but I've left it in above for similarity to the earlier examples and to illustrate that it works. The second snippet splits the two statements into separate lines, also with identical results.

int i = 0;
var qPeople4 = mcontext.tblPeoples.Select<ME.tblPeople,ME.tblPeople>(person => { i += 1; return person; });
int i = 0;
var qPeople1 = from ME.tblPeople person in mcontext.tblPeoples
               select person;
var qPeople5 = qPeople1.Select(person => { i += 1; return person; });
Zooba
Your **qPeople3** statement gives me the CSC 3.5 compile error: `A lambda expression with a statement body cannot be converted to an expression tree`
John K
Actually none of those compile - they all give the compile error stated above.
John K
Now I realize you might not have seen the data context in the source code. An `AsEnumerable` would be needed as is answered here http://stackoverflow.com/questions/3261037/3261819#3261819.
John K
Ah, I see. I only tested it with LINQ to Objects, not LINQ to SQL. My bad. The AsEnumerable() call changes it from an IQueryable to an IEnumerable. I'll add an addendum to my answer in case people don't read the comments (and I upvoted dahlbyk's answer, since he picked up on my omission).
Zooba
+2  A: 

There are two kinds of lambda expressions: anonymous delegates and expression trees. The former kind is used by LINQ to Objects, and allows any valid anonymous method body. The latter kind is used by LINQ to SQL and requires that its body be a single expression. This expression is then passed into the L2SQL runtime and manipulated into the SQL sent to the server.

To perform your inline work, you will need to use two steps: 1) get SQL data with a valid select expression, then 2) manipulate that data as an IEnumerable<> with LINQ to Objects to do your inline work. That could look something like this:

var qPeople1 = from ME.tblPeople person in mcontext.tblPeoples
              select person;

var i = 0;
var qPeople2 = qPeople1.AsEnumerable().Select(person => {
                   i += 1;
                   return person; 
               });
dahlbyk
That clarifies my situation. I'm glad you saw the DataContext being used for SQL. I ran the code and it works great. Thanks.
John K