首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用C#中的LINQ从使用组返回和值

如何使用C#中的LINQ从使用组返回和值
EN

Stack Overflow用户
提问于 2017-03-04 20:20:32
回答 2查看 1.4K关注 0票数 0

我使用LINQ搜索与Group和Sum相关的许多主题,但我不能在Group、Having之间使用组合式,然后返回Interger。有人能帮上忙吗

我有一个数据表

代码语言:javascript
复制
|---------------------|------------------|
|      Name           |     Count        |
|---------------------|------------------|
|          Apple      |         34       |
|---------------------|------------------|
|          Apple      |         12       |
|---------------------|------------------|
|          Orange     |         10       |
|---------------------|------------------|

我想用LINQ来返回关于苹果总量为46的整数。

这是我的代码,但不能运行

代码语言:javascript
复制
 int total = dt.AsEnumerable().Where(tt => tt.Field<string>("Name") == "Apple")
        .GroupBy(tt => tt.Field<string>("Name"))
        .Sum(tt => Int32.Parse(tt.Field<string>("Count")))

所有代码和问题

代码语言:javascript
复制
DataTable dt = new DataTable();
        DataColumn col1 = new DataColumn("Name");
        DataColumn col2 = new DataColumn("Count");

        dt.Columns.Add(col1);
        dt.Columns.Add(col2);

        DataRow row = dt.NewRow();
        row[col1] = "Apple";
        row[col2] = 34;
        dt.Rows.Add(row);

        DataRow row1 = dt.NewRow();
        row1[col1] = "Apple";
        row1[col2] = 12;
        dt.Rows.Add(row1);

        DataRow row2 = dt.NewRow();
        row2[col1] = "Orange";
        row2[col2] = 10;
        dt.Rows.Add(row2);

        int total = dt.AsEnumerable().Where(tt => tt.Field<string>("Name") == "Apple")
             .GroupBy(tt => tt.Field<string>("Name"))
             .Sum(tt => Int32.Parse(tt.Field<string>("Count")));

错误:

严重性代码描述项目文件行抑制状态错误CS1929 'IGrouping‘不包含“字段”的定义,最好的扩展方法重载'DataRowExtensions.Field(DataRow,string)’需要一个'DataRow‘WindowsFormsApplication1 c:\DataRow\admin\documents\visual studio WindowsFormsApplication1 46 Active的接收器。

谢谢大家,

EN

回答 2

Stack Overflow用户

发布于 2017-03-04 20:49:32

您有一个逻辑问题,这不是“无法运行”的原因。因为你只想还苹果,所以不需要分组。简单地总结一下!如果要返回不同产品的总计数,则必须按产品分组。

然后,您需要对Field<T>使用一个类型参数,该参数与表列的类型相匹配。如果您有int表列( Server或数字长访问权限),则必须使用Field<int>

代码语言:javascript
复制
int total = dt.AsEnumerable()
    .Where(row => row.Field<string>("Name") == "Apple")
    .Sum(row => row.Field<int>("Count"));

还请注意,在C#中,默认的字符串比较模式是区分大小写的。因此,请确保具有正确大小写的列名和筛选值。

还请注意,GroupBy返回一个IEnumerable<IGrouping<TKey, TSource>>,而不是一个IEnumerable< TSource>!因此,您需要这样做:

代码语言:javascript
复制
var totals = dt.AsEnumerable()
    .GroupBy(row => row.Field<string>("Name")
    .Select(g => new { Name = g.Key, Total = g.Sum(row => row.Field<int>("Count")));

IGrouping<TKey, TSource>有一个Key属性并实现了一个IEnumerable<TSource>。因此,您可以在上面应用Sum函数。

这将返回具有NameTotal属性的匿名类型的枚举。

SQL中WHERE和WHERE的区别是在分组之前执行WHERE,在分组之后执行WHERE。在LINQ中,这些都是应用于Where之前或GroupBy之后的GroupBy函数。这意味着您可以像以前一样使用Where,在DataRows上应用于GroupBy之前,或者在GroupBy应用于IGrouping<string, DataRow>s之后使用Where。甚至可以在Select之后使用Where (如果您没有使用LINQ或其他LINQ,即如果您没有使用O/R-映射器)。

票数 1
EN

Stack Overflow用户

发布于 2017-03-04 22:32:13

如果计数是数字类型(否则可以使用Convert.ToInt32(r["Count"])),可能会容易一些。

代码语言:javascript
复制
DataTable dt = new DataTable();
dt.Columns.Add("Name");                 // typeof(string) by default
dt.Columns.Add("Count", typeof(int));   // specify numeric type
dt.Rows.Add("Apple", 34);
dt.Rows.Add("Apple", 12);
dt.Rows.Add("Orange", 10);

// to sum the Count only for Apple:
int AppleCount = dt.Rows.Cast<DataRow>().Sum(r => "Apple".Equals(r[0]) ? (int)r[1] : 0); 

// or group by Name if you need the Count of more than one Name
var lookup = dt.Rows.Cast<DataRow>().ToLookup(r => r[0] as string, r => (int)r[1]);
int iAppleCount = lookup["Apple"].Sum();    // 46
int iOrangeCount = lookup["Orange"].Sum();  // 10

// if Count is numeric tupe, you can also Compute them like this:
var oAppleCount = dt.Compute("Sum(Count)", "Name = 'Apple'"); // 46 (object {long})
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42600943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档