tags:

views:

223

answers:

3

Why is this thing giving the message in the second line (i.e. list convertion)?

IEnumerable<Order> MyQuery = from order in dataContext.GetTable<Order>()
                          where order.ID == 1
                          select new Order() {ID = order.ID, OrderDate=order.OrderDate };

            List<Order> list = new List<Order>(MyQuery);

The message:

Explicit construction of entity type 'Order' in query is not allowed.

If it is already converted into an IEnumerable. The what is its problem to convert it into a List?

Again, if I write the following, it works:

IEnumerable<Order> MyQuery = from order in dataContext.GetTable<Order>()
                                         where order.ID == 1
                                         select order;
List<Order> list = new List<Order>(MyQuery);

Why? What is the trick?

+3  A: 

The problem isn't in the list construction, it's in this line:

select new Order() {ID = order.ID, OrderDate=order.OrderDate };

The issue is that you cannot explicitly create an entity within a Query. This is occurring when you try to create your list because the IEnumerable is not actually enumerated until you try to wrap this in the new List<Order> line due to deferred execution of your query.

It looks like you're trying to retrieve the orders themselves. The answer is probably to just select the order, and not try to construct a NEW order:

IEnumerable<Order> MyQuery = from order in dataContext.GetTable<Order>()
                      where order.ID == 1
                      select order;

Also, there is no reason to make the enumerable, then turn it into a list. You can just do:

List<Order> list = (from order in dataContext.GetTable<Order>()
                      where order.ID == 1
                      select order).ToList();
Reed Copsey
+2  A: 

Well, you're only really executing the query when you convert it to a list. Before that it's just an arbitrary IQueryable.

Two options (assuming you're trying to avoid fetching all the other columns):

  1. Use an anonymous type:

    var query  = from order in dataContext.GetTable<Order>()
                 where order.ID == 1
                 select {ID = order.ID, OrderDate=order.OrderDate };
    
    
    var list = query.ToList();
    
  2. Use AsEnumerable to create new orders after they've come down from the LINQ provider. Note that they won't be proper entities at this point:

    var query  = dataContext.GetTable<Order>()
                      .Where(order => order.ID == 1)
                      .AsEnumerable() // Do everything else "in process"
                      .Select(order => new Order {ID = order.ID, 
                                                  OrderDate=order.OrderDate });
    
    
    List<Order> list = query.ToList();
    
Jon Skeet
Jon: In your option 1, it probably won't compile, because you're trying to construct a List<Order> from an IEnumerable<anonymous_type>, right?
Reed Copsey
Oops, will fix to use var (which is what I meant :)
Jon Skeet
I would be wary of disconnected objects in a connected environment.
leppie
@leppie: So would I, hence the note :) However, it may be legitimate in this particular case.
Jon Skeet
+2  A: 

The first answer to this post illustrates what's going on.

The usage pattern for entities is that they are created outside of queries and inserted into tables via the DataContext and then later retrieved via queries, never created by queries.

Consider, you can use the .ToList() method to convert to a list.

cloggins