Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从datatable中提取两个内容的总和_C#_Sql_Sql Server_Datatable - Fatal编程技术网

C# 从datatable中提取两个内容的总和

C# 从datatable中提取两个内容的总和,c#,sql,sql-server,datatable,C#,Sql,Sql Server,Datatable,我在SQL Server数据库中有一个包含许多列的表,但重要的列是LoggedState和InteractionType 我需要找到中断代理的数量和空闲代理的数量 我试过的 它工作得很好,但我想问的是,是否有一种方法(如分组)可以避免使用foreach语句 var breakAgents = from row in DTgraph.AsEnumerable() where row["LoggedState"].ToString().Trim().ToLower() == "break" sele

我在SQL Server数据库中有一个包含许多列的表,但重要的列是
LoggedState
InteractionType

我需要找到中断代理的数量和空闲代理的数量

我试过的 它工作得很好,但我想问的是,是否有一种方法(如分组)可以避免使用
foreach
语句

var breakAgents = from row in DTgraph.AsEnumerable()
where row["LoggedState"].ToString().Trim().ToLower() == "break"
select row;
var breakAgentsCount = breakAgents.Count();


您可以像这样执行sql查询:

select 
   sum(case when LoggedState = "break" then 1 else 0 end) break_count,
   sum(case when LoggedState = "activo" and InteractionType is null then 1 else 0 end) active_count
from table_name

使用LINQ提供的计数函数,以下解决方案应该可以工作:

// Cast the rows to a collection of DataRows.
IEnumerable<DataRow> collection = DTgraph.Rows.Cast<DataRow>();

// Get the number of Break Agents.
int numberOfBreakAgents = collection.Count(row => row["LoggedState"].ToString().Trim().ToLower() == "break");
// Get the number of Idel Agents.
int numberOfIdelAgents = collection.Count(row => row["LoggedState"].ToString().Trim().ToLower() == "activo" && row["InteractionType"] == DBNull.Value);
//将行强制转换为数据行集合。
IEnumerable collection=DTgraph.Rows.Cast();
//获取中断代理的数量。
int numberOfBreakAgents=collection.Count(行=>row[“LoggedState”].ToString().Trim().ToLower()=“break”);
//获取Idel代理的数量。
int numberOfIdelAgents=collection.Count(行=>row[“LoggedState”].ToString().Trim().ToLower()==“activo”&&row[“InteractionType”]==DBNull.Value);
强制转换用于允许在DataRow集合上使用LINQ


另一个选项是将DataRow集合强制转换为DataRow类型的列表。然后使用ForEach(也是LINQ)来确定代理类型:

List<DataRow> collection = DTgraph.Rows.Cast<DataRow>().ToList();

collection.ForEach(row =>
{
    if (row["LoggedState"].ToString().Trim().ToLower() == "break")
        numberOfBreakAgents++;
    else if (row["LoggedState"].ToString().Trim().ToLower() == "activo" && row["InteractionType"] == DBNull.Value)
        numberOfIdelAgents++;
});
List collection=DTgraph.Rows.Cast().ToList();
collection.ForEach(行=>
{
如果(行[“LoggedState”].ToString().Trim().ToLower()=“break”)
numberOfBreakAgents++;
else if(行[“LoggedState”].ToString().Trim().ToLower()==“activo”&&row[“InteractionType”]==DBNull.Value)
numberOfIdelAgents++;
});

上面的示例与您的示例非常相似,但编写得稍短一些,并且没有使用两个字符串(LoggedState和InteractionType)。

您可以使用Linq中的
Group
函数:

var loggedStateGroups = dt.AsEnumerable().GroupBy(d => d["LoggedState"].ToString(), (group, row) => new
{
    LoggedState = group,
    AllCount = row.Count(),
    NullCount = row.Where(r => r["InteractionType"] == DBNull.Value).Count()
});
它将按LoggedState分组,每个匹配行的计数(
AllCount
)和InteractionType为
DBNull.Value
NullCount
)的行的计数

然后,我们可以通过执行以下操作来选择所需的计数:

int numberOfBreakAgents = loggedStateGroups.Where(y => y.LoggedState == "break").First().AllCount;
int numberOfIdelAgents = loggedStateGroups.Where(y => y.LoggedState == "activo").First().NullCount;
注意,我只是先使用
,假设您总是有结果。如果不总是有结果,则应使用
FirstOrDefault
并执行空检查

您可以在使用
组之前进行筛选,方法是根据您的数据在其中添加以下

.Where(r => r["LoggedState"].ToString() == "break" || r["LoggedState"].ToString() == "activo")
我已使用以下设置对此进行了测试:

DataTable dt = new DataTable();
dt.Columns.Add("LoggedState");
dt.Columns.Add("InteractionType");

dt.Rows.Add("break", "inter1");
dt.Rows.Add("activo", DBNull.Value);
dt.Rows.Add("break", "inter1");
dt.Rows.Add("break", "inter2");
dt.Rows.Add("activo", "inter2");
对于
numberOfBreakAgents
numberOfIdelAgents
,我分别得到
3和
1

使用FirstOrDefault进行编辑:

如果您想执行上面提到的空检查,可以将上面的两个
int
声明行替换为:

var breakAgents = loggedStateGroups.Where(y => y.LoggedState == "break").FirstOrDefault();
var idelAgents = loggedStateGroups.Where(y => y.LoggedState == "activo").FirstOrDefault();

int numberOfBreakAgents = breakAgents != null ? breakAgents.AllCount : 0;
int numberOfIdelAgents = idelAgents != null ? idelAgents.NullCount : 0;
这是第一个日志数据状态为“break”或
null(如果没有)的组。然后,如果组不为null,则分配
numberOfBreakAgents
属性;如果组为null,则分配
AllCount
属性

对于
numberOfIdelAgents
也做了类似的事情,除了我们过滤“activo”组并使用
NullCount
属性,因为我们对所有行都不感兴趣,我们只对那些InteractionType为
DBNull.Value
的行感兴趣,这些行是我们在
NullCount
属性中捕获的

如果结果集包含LoggedState为“activo”的零行或LoggedState为“break”的零行,则必须执行null检查。在这种情况下,
.First()
将返回
null
,从中访问
AllCount
NullCount
将导致“序列不包含元素”异常

使用以下数据表定义将突出显示差异,因为它会导致使用
First()
numberOfBreakAgents
异常,但使用
FirstOrDefault
时正确返回
0

DataTable dt = new DataTable();
dt.Columns.Add("LoggedState");
dt.Columns.Add("InteractionType");

dt.Rows.Add("activo", "inter1");
dt.Rows.Add("activo", DBNull.Value);
dt.Rows.Add("activo", "inter1");
dt.Rows.Add("activo", "inter2");
dt.Rows.Add("activo", "inter2");


这可能不关我的事,但你似乎在第3行有一个多余的分号,不应该在那里。@Matthijs谢谢你在你的第一行,没有
行中的
位置更改为使DTgraph成为IEumerableeter
DBNull.Value
你有
。为什么是
?对不起,那是个错误-把它取出来了。+1表示努力。我还没有找到写答案,因为我的队友删除了一些数据。我没有表,我只有存储过程。这个查询可以满足您的需要,您可以在存储过程中使用它。我可以使用存储过程,我在小组里工作,我没有很多权限。你们能更新你们的答案并使用第一个或默认的pleae吗+1使用默认值中的第一个时,您删除了
activo
条件中的null检查。这对我来说是非常重要的,我认为没有必要先默认,因为现在结果是空的,尽管你的代码给了我零,这很好,我不认为我这样做了。
activo
上的空检查位于填充组的
NullCount
属性的联接中。在我的
FirstOrDefault
代码中,我正在检查是否有任何与“activo”匹配的LoggedStates,如果有,我将采用NullCount(与“break”类似的,在其中的行数,而不是AllCount)组。@MarcoDinatsoli我已再次更新了答案以添加更多说明。我认为您可能确实需要空检查,但我对您的数据了解不够,无法确定。我尝试了您的第一种方法,但我一直得到零,尽管我可以看到结果有值扫描您检查集合是否已填充?因此,在演员阵容结束后。
var breakAgents = loggedStateGroups.Where(y => y.LoggedState == "break").FirstOrDefault();
var idelAgents = loggedStateGroups.Where(y => y.LoggedState == "activo").FirstOrDefault();

int numberOfBreakAgents = breakAgents != null ? breakAgents.AllCount : 0;
int numberOfIdelAgents = idelAgents != null ? idelAgents.NullCount : 0;
DataTable dt = new DataTable();
dt.Columns.Add("LoggedState");
dt.Columns.Add("InteractionType");

dt.Rows.Add("activo", "inter1");
dt.Rows.Add("activo", DBNull.Value);
dt.Rows.Add("activo", "inter1");
dt.Rows.Add("activo", "inter2");
dt.Rows.Add("activo", "inter2");