2009-06-05 10 views
3

Imaginez qu'il existe deux tables. Une commande peut avoir plusieurs OrderStatus, qui peuvent être appelés OrderStatusHistory. Je vais avoir un StronglyTypeObject ordre, qui descripted comme suitLINQ à SQL SubSelect Like Query

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

Ce StatusID dans l'objet de la commande est destiné à être le courant (dernier) StatusID du OrderStatus tableau.

J'ai essayé de créer une liste IQueryable d'objets avec LINQ. Voici mon, ne fonctionne pas;), Code Linq

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 
      } 

J'ai aussi essayé de travailler avec Max (p => p.XXX) mais il n'a pas fonctionné. Est-ce que quelqu'un a un indice sur ce problème?

Toute aide serait appréciée ...

Gordon

+0

Cela illustre pourquoi j'ai critiqué Linq et des solutions ORM similaires. Voici un problème qui a une solution largement connue et assez simple dans un langage bien établi. Afin d'obtenir des avantages théoriques, vous abandonnez la productivité réelle. Est-ce que les gains que vous avez obtenus de Linq l'emportent sur le temps nécessaire pour apprendre une manière redondante (et idiosyncratique) d'interroger des données? Voir http://stackoverflow.com/questions/458802/doesnt-linq-to-sql-miss-the-point-arent-orm-mappers-subsonic-etc-sub-opti pour la discussion. –

Répondre

2

Based sur votre commentaire, j'ai mis à jour le ci-dessous pour utiliser First et, dans ce cas, vous devrez faire un OrderByDescending sur la clé pour l'obtenir dans le bon ordre.

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 
     } 

En outre, si vous avez une relation FK défini, il devrait être beaucoup plus facile d'obtenir la dernière StatusID sans créer un objet intermédiaire. Dans ce cas, je pense que vous pouvez utiliser Last (si les objets sont préchargés) puisque vous allez faire LINQtoObjects, pas LINQToSQL. YMMV. Ce dernier pourrait être ajouté en tant que méthode sur une classe partielle pour ORDER de sorte que vous pouvez vous y référer comme.

var currentStatus = order.CurrentStatus; 

public partial class ORDER 
{ 
    public int64 CurrentStatus 
    { 
     get 
     { 
      return this.OrderStatuses.Last().StatusId; 
     } 
    } 
} 
+0

Merci pour votre réponse très utile. De la logique de la requête LINQ, je l'avais écrit exactement comme vous l'avez fait. Le problème que j'ai en ce moment, c'est que l'instruction lève une exception System.NotSupportedException. Le Queryoperator "Last" n'est pas supporté.Thats je ne comprends pas. – Gordon

+0

Ok, puis OrderByDescending et utilisez First à la place. Je vais mettre à jour. – tvanfosson

1

bien, que diriez-vous: (prendre deux, ordre décroissant et prenez la première .. 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() 
     } 
+0

C'est l'approche similaire que j'utilisais. il sélectionne le statut Max() StatusId de la table OrderStatus. Le problème est qu'un OrderStatus peut être 1 = order_received, 2 = order_payed, 3 = order_shipped, 4 = order_changed. Ainsi, après que le StatusId a été mis à 4, il changera après un travail effectué par les vendeurs à 2, une fois que le paiement de la modification est répété. La requête nous donnera toujours 4, dans l'exemple. C'est pourquoi j'utilisais Last() pour obtenir le dernier StatusID. – Gordon

+0

Cela provoque une exception "System.NotSupportedException: QueryOperator" Last "n'est pas pris en charge". Des idées? – Gordon