100

I am working with .NET4.5 and VS2013, I have this query that gets dynamic result from db.

dynamic topAgents = this._dataContext.Sql(
    "select t.create_user_id as \"User\", sum(t.netamount) as \"Amount\" from transactiondetail t where t.update_date > sysdate -7 group by t.create_user_id")
    .QueryMany<dynamic>();

Following statement fails with compilation error Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type without even allowing me to run it

topAgents.ToList().Select(agent => new
{
    User = agent.User != null ? string.Format("{0}", agent.User).Replace("CORPNTGB\\", "") : null,
    Amount = agent.Amount
});

while this one with foreach works just fine.

var data = new List<List<object>>();
foreach (dynamic agent in topAgents)
{
    data.Add(new List<object>
    {
        agent.User != null ? string.Format("{0}", agent.User).Replace("CORPNTGB\\", "") : null,
        agent.Amount
    });
}

In my eyes after I topAgents.ToList() they could be interpreted as equivalent, is it because I explicitly state that var data = new List<List<object>>(); that second statement is allowed by compiler?

Why doesn't compiler allow LINQ select, but allows for each`?

1
  • 2
    Does topAgents have to be dynamic? Does it work if you use var instead?
    – DavidG
    Nov 27, 2014 at 11:27

1 Answer 1

128

The problem is that topAgents is dynamic - so your ToList() call is dynamic, and so is Select. That has issues that:

  1. you can't use lambda expressions for dynamic calls like this;
  2. dynamic calls don't find extension methods anyway.

Fortunately, the operations don't need to be dynamic just because the element type is dynamic. You could use:

IEnumerable<dynamic> topAgents = ...;

... or just use var. Both of those should be fine.

2
  • Thank you, I somehow failed to see that topAgents was dynamic all this time. Nov 27, 2014 at 11:33
  • I had a foreach loop with a dynamic object in a view. For this object I wanted to use a Linq where constraint, which of course didn't work. So I provided the dynamic object with a simple cast: ((IList<MyType>)ViewBag.MyObject).Where(p => p.MyProperty = property). This works very well!
    – peter70
    Sep 13, 2022 at 5:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.