views:

675

answers:

2

Hi folks,

imagine there are two tables.

Order
+----------------+
| ID             |
| Name           |
+----------------+

OrderStatus
+----------------+
| ID             |
| OrderId        |
| StatusId       |
+----------------+

A Order can have more than one OrderStatus, which could be called OrderStatusHistory. I'll have an StronglyTypeObject Order, which is descripted as follows

namespace my.project
{
    public class Order
    {
        Int64 OrderId { get; set; }
        String Name { get; set; }
        Int64 StatusId { get; set; }
    }
}

This StatusId in the Order Object is meant to be the current (last) StatusId from the OrderStatus Table.

I have tried to build a IQueryable List of Objects with LINQ. Here is my, not working ;), Linq Code

var result = from r in dbContext.ORDER
             select new Order
             {
                 OrderId = r.ID,
                 Name = r.Name,
                 StatusId = dbContext.OrderStatus
                            .Where(p => p.OrderId == r.ID).Last().StatusId
             }

I have also tried working with Max(p=>p.XXX) but it hasn't worked out. Does anyone has a hint on this problem?

Any Help would be much appreciated...

Gordon

A: 

alright, how about this: (take two, order descending and take first .. top 1 )

var result = from r in dbContext.ORDER
         select new Order
         {
             OrderId = r.ID,
             Name = r.Name,
             StatusId = dbContext.OrderStatus
                                 .Where(p => p.OrderId == r.ID)
                                 .OrderByDescending(p => p.OrderID)
                                 .Select(p => p.StatusId)
                                 .FirstOrDefault()
         }
John Boker
That is the similar approach I was using. it selects the Max() StatusId from the OrderStatus Table. The Problem is say an OrderStatus can be1 = order_received, 2 = order_payed, 3 = order_shipped, 4 = order_changed.So after the StatusId was set to 4, it will change after some work by the sales people to 2 again, once the payment of the change is repeated. The Query will give us always 4, in the example. That is why I was using Last(), to get the lastest StatusID.
Gordon
That throws an Exception "System.NotSupportedException: QueryOperator "Last" is not supported". Any ideas?
Gordon
+1  A: 

Based on your comment, I've updated the below to use First and, in that case, you will need to do an OrderByDescending on the key to get it in the right order.

var result = from r in dbContext.ORDER
         select new Order
         {
             OrderId = r.ID,
             Name = r.Name,
             StatusId = dbContext.OrderStatus
                        .Where(p => p.OrderId == r.ID)
                        .OrderByDescending( p => p.ID )
                        .First()
                        .StatusId
         }

Also, if you have a FK relationship defined, it should be much easier to get the last StatusId without creating an intermediate object. In this case, I think you can use Last (if the objects are preloaded) since you'll be doing LINQtoObjects, not LINQToSQL. YMMV.

var currentStatus = order.OrderStatuses.Last().StatusId;

The latter could be added as a method on a partial class for ORDER so that you can refer to it as.

var currentStatus = order.CurrentStatus;

public partial class ORDER
{
     public int64 CurrentStatus
     {
         get
         {
             return this.OrderStatuses.Last().StatusId;
         }
     }
}
tvanfosson
Thanks for your very helpful Answer. From the logic of the LINQ Query I had written it exactly like you did. The Problem I having right now is, that the statement is throwing an System.NotSupportedException. The Queryoperator "Last" is not supported. Thats I doesn't understand.
Gordon
Ok, then OrderByDescending and use First instead. I'll update.
tvanfosson