2012-01-24 37 views
8

我想通过ItemNumber将我的LINQ查询分组,并返回整个表的总数为Quantity在C#中的Lambda表达式组

Example: 
ItemNumber - ItemName - Quantity 
100   Item1  1 
150   Item2  2 
100   Item1  2 
200   Item3  1 
150   Item2  2 

Should be: 
ItemNumber - ItemName - Quantity 
100   Item1  3 
150   Item2  4 
200   Item3  1 

这是我想组查询:

public IQueryable<WebsiteOrderStatus> GetOrderStatusByAccountNumberWithoutDeleted 
     (string accountNumber) 
{ 
    return db.WebsiteOrderStatus 
      .Where(x => x.AccountNumber == accountNumber && x.LastUpdatedStatus != 1); 
} 

到目前为止我最好的结果(这不可能,虽然编译):

public IQueryable<IGrouping<Int32?, WebsiteOrderStatus>> lol(string accountNumber) 
{ 
    db.WebsiteOrderStatus 
     .Where(x => x.AccountNumber == accountNumber && x.LastUpdatedStatus != 1) 
     .GroupBy(g => g.ItemNumber) 
     .Select(g => new 
        { 
         g.Key.ItemNumber, 
         Column1 = (Int32?)g.Sum(p => p.Quantity) 
        }); 
} 

编辑:

感谢大家的回复,我必须面对它。在我看来,这些匿名类型非常难以工作,所以我找到了另一种解决方案。

我做了另一种方法,它总结了用户项目的数量并将其分组。

public IQueryable<WebsiteOrderStatus> GetOrderStatusByAccountNumberWithoutDeleted(string accountNumber) 
{ 
    return db.WebsiteOrderStatus.Where(x => x.AccountNumber == accountNumber && x.LastUpdatedStatus != 1).GroupBy(x => x.ItemNumber).Select(grp => grp.First()); 
} 

public int GetQuantityOfUsersItem(string accountNumber, string itemNumber) 
{ 
    return db.WebsiteOrderStatus.Where(x => x.ItemNumber == itemNumber && x.AccountNumber == accountNumber).Sum(x => x.Quantity); 
} 

在网页,我有我的GridView我所做的:

var query = websiteOrderStatusRep.GetOrderStatusByAccountNumberWithoutDeleted(AppSession.CurrentLoginTicket.AccountNumber).Select(x => new { x.ItemName, x.ItemNumber, x.FormatName, x.Price, x.Status, x.Levering, Quantity = websiteOrderStatusRep.GetQuantityOfUsersItem(x.AccountNumber, x.ItemNumber)}); 
+1

不知道还有什么是错的,但最起码​​,你”在第二个样本中重新丢失了一个'return'。 – Ani

+0

你得到的编译错误是什么? –

+1

也许他试图把g.Key当作一个对象,而它只是int。如果他想要结果中的项目名称,那么他还必须将其存储在关键对象中(并将关键字设置为可比较的对象),或者从组enumberator中的第一个条目中读取它。 – Rup

回答

10
public IQueryable<IGrouping<Int32?, WebsiteOrderStatus>> lol(string accountNumber) 
{ 
    db.WebsiteOrderStatus 
     .Where(x => x.AccountNumber == accountNumber && x.LastUpdatedStatus != 1) 
     .GroupBy(g => g.ItemNumber) 
     .Select(g => new 
        { 
         ItemNumber = g.Key, 
         ItemName = g.First().ItemName, 
         Count = g.Sum(item => item.Quantity) 
        }); 
} 
3

我觉得Select应该是:

.Select(g => new 
       { 
        ItemNumber = g.Key, 
        Column1 = (Int32?)g.Sum(p => p.Quantity) 
       }); 

注意,在第一线的变化匿名类型。分组的关键在于项目编号。

5

唯一的问题,我看到您的查询中

  1. 缺少return声明按照意见
  2. select语句应该是:

-

.Select(g => new { 
     ItemNumber = g.Key, 
     Total = g.Sum(p => p.Quantity) 
    }); 

编辑:如果你想要得到的,可以说ItemNumber和ITEMNAME,在生成的对象,还必须在组这些领域

db.WebsiteOrderStatus 
    .Where(x => x.AccountNumber == accountNumber && x.LastUpdatedStatus != 1) 
    .GroupBy(g => new { g.ItemNumber, g.ItemName }) 
    .Select(g => new 
       { 
        ItemNumber = g.Key.ItemNumber, 
        ItemName = g.Key.ItemName, 
        Count = g.Sum(item => item.Quantity) 
       }); 
+0

似乎它只返回ItemNumber和Total。我想要的是整个表只是一个名为total的列,其中包含数量总计 – KLIM8D

+0

@ KLIM8D - 请参阅更新 – Jamiec

+0

没关系,所以我想在结果中获得的每个对象都必须在分组中。我实际上在表格中还有5个其他字段,除了我需要的所有字段必须包含在groupby中之外,是否还有更好的方法来执行此分组? – KLIM8D

7
public IQueryable<OrderStatus > lol(string accountNumber) 
{ 
    return db.WebsiteOrderStatus 
     .Where(x => x.AccountNumber == accountNumber && x.LastUpdatedStatus != 1) 
     .GroupBy(g => g.ItemNumber) 
     .Select(g => 
       new OrderStatus //This is your custom class, for binding only 
       { 
        ItemNumber = g.Key, 
        ItemName = g.First().ItemName, 
        Quantity = g.Sum(g => g.Quantity) 
       } 
     ); 
} 
+0

我们差不多 - 没有错误,直到我试图绑定我的查询到一个gridview。 我得到这个异常:System.NotSupportedException:不允许在查询中显式构造实体类型'GWportal.BusinessLayer.Repository.WebsiteOrderStatus'。 – KLIM8D

+2

'实体可以在查询之外创建,并使用DataContext插入到数据存储中。然后您可以使用查询来检索它们。但是,您不能创建实体作为查询的一部分。“在这种情况下,您必须创建一个自定义类来绑定并将'WebsiteOrderStatus'映射到该类的对象。 –

2

您不能返回值的类型使用匿名类型。所以你永远不会编译代码。

另外你的linq表达式有IQueryable < [匿名类型]>结果类型。

我相信你可以做这样的事情:

public IQueryable<OrderStatus> lol(string accountNumber) 
{ 
    db.WebsiteOrderStatus 
     .Where(order => order.AccountNumber == accountNumber && order.LastUpdatedStatus != 1) 
     .GroupBy(order => order.ItemNumber) 
     .Select(grouping => new OrderStatus //This is your custom class, for binding only 
        { 
         ItemNumber = grouping.Key, 
         ItemName = grouping.First().ItemName, 
         Quantity = grouping.Sum(order => order.Quantity) 
        }); 
} 

I`ve固定我的答案太:)

+0

为什么你不能使用匿名类型作为返回值。 – Jamiec

+1

如何在方法的签名中指定它? –

+0

MSDN: 您无法将方法的字段,属性,事件或返回类型声明为具有匿名类型。同样,您不能将方法,属性,构造函数或索引器的正式参数声明为具有匿名类型。要将匿名类型或包含匿名类型的集合作为参数传递给方法,可以将参数声明为类型对象。但是,这样做会破坏强打字的目的。如果您必须存储查询结果或将其传递到方法边界外,请考虑使用普通的命名结构或类而不是匿名类型。 –