C# 如何附加两个linq查询的结果
我有两个LINQ's在下面C# 如何附加两个linq查询的结果,c#,C#,我有两个LINQ's在下面 public IEnumerable<TurbineStatus> turStatus() { var result1 = (from s in _db.masterData group s by s.current_turbine_status into g select new TurbineStatus {
public IEnumerable<TurbineStatus> turStatus()
{
var result1 = (from s in _db.masterData
group s by s.current_turbine_status into g
select new TurbineStatus
{
status = g.Key,
numberOfTurbines = g.Count()
}
).ToList().OrderByDescending(s => s.status);
int result12= _db.masterData.Select(s=>s.turbine_name).Count();
return result;
}
第一个查询返回涡轮机及其状态
第二个返回所有涡轮机的编号
如何将它们连接在一起
例如:result1
示例查询结果是(“RUN”:2,“STOP”:4,…)。这意味着有4台涡轮机停止运行,2台涡轮机正在运行
第二个linq(result2)返回所有涡轮机的数量,这是一个整数。您应该重新考虑您的类结构。一个单独的
状态
知道该类的其他实例以便对它们进行计数,这违反了单一可重复性原则。因此,一个状态
应该只是一个状态
,而不是关于其他状态
的一些聚合信息
因此,我建议将您的状态设置为一个枚举:
enum TurbineStatus { OnRun, Stop }
现在,像您已经做的那样对风轮机进行分组,但不是将每个状态的项目数存储在状态本身中,而是存储在字典中,甚至是另一个类中,或者(如在我的代码中)存储在元组中:
public IEnumerable<(TurbineStatus, int)> turStatus()
{
var result = (from s in _db.masterData
group s by s.current_turbine_status into g
select (g.Key, numberOfTurbines = g.Count())
).ToList().OrderByDescending(s => s.status);
return result;
}
然而,请注意,你不能或不应该订购字典。如果需要,请使用SortedDictionary
如果还需要整个数据库中所有项目的计数,则可以按照@Fildor建议的方法引入out
-参数。或者在调用上述方法后添加另一个查询:
var turstatus = turstatus();
var totalCount = turStatus.Select(x => x.Item2).Sum(); // assuming the first (tuple-based) approach)
var totalCount = turStatus.Select(x => x.Value).Sum(); // this is for the dictionary-based approach
免责声明:正如@HimBromBeere在评论中提到的那样,拥有一个Status
类,它实际上“知道”有多少实例是不干净的设计,因此您可能需要重新考虑这一点
那就是:“我如何返回两个不同的东西?”
返回+输出参数
//函数的签名如下所示:
int GetTurbineNumbers(out IEnumerable)//再次:重新考虑该类
//反过来
IEnumerable GetTurbineNumber(out int totalTurbines)
将out参数设置为列表结果,只需返回总数(反之亦然)
创建一个结果类
类统计{
公共IEnumerable{get;set;}
公共整数总计{get;set;}
}
创建一个实例,设置属性并返回它
返回元组
(IEnumerable,int)GetTurbineNumber()
返回字典
IDictionary getTurbineNumber()
{
//在字典中填入statusname、count和“total”、count
//还它
}
当然,也可以使用状态枚举作为键,而不是字符串。只是枚举必须有一个“Total”项,这会再次使它有点“脏”。“总体”状态应该是什么。当然,你可以做一个特殊的枚举“TurbineStatus统计学家”或类似的东西。。。但我离题了
看看他,布罗姆比尔的回答
仅列举一些可能性
但是问问自己“我应该这么做吗?”。一个返回“2件事”的函数破坏了“只做一件事”的原则。所以,我个人会选择:有两个单独的函数用于状态计数,一个用于合计。或者选择一种提取结果的方法,使它们不再是“两件事”,而是一组统计数据。有两种方法可以做到这一点
一种方法是将总数包含在列表中的所有项目中,如下所示:
public IEnumerable<TurbineStatus> turStatus()
{
int totalCount = _db.masterData.Select(s=>s.turbine_name).Count();
var result1 = (from s in _db.masterData
group s by s.current_turbine_status into g
select new TurbineStatus
{
status = g.Key,
numberOfTurbines = g.Count(),
total = totalCount,
}
).ToList().OrderByDescending(s => s.status);
return result;
}
除此之外,我觉得你的第二个问题有点奇怪。为什么要选择涡轮机名称
,然后对元素进行计数?为什么不直接使用Count
而不使用Select
?您可以在结果列表中使用out参数并返回数字,或者返回一个元组,或者您可以创建一个具有两个属性的结果类,如果这是(我想是)。@HimBromBeere我很好奇,为什么它是一个糟糕的类结构?因为它打破了该类的单个实例的职责,从而了解了一组实例。或者换句话说:为什么一个状态
-类应该有一个编号
-属性?我希望状态
只是一个状态
,没有别的。好吧,这个问题的答案可能还包括“重新考虑你的设计,因为…”,IMHO。total=totalCount,
老实说?在该类的所有实例上都相等的属性?为什么还要有那份财产?你在任何地方都不需要它。这是一个非常糟糕的设计,IMO“有两种方法可以做到这一点”-我要说,这表明(原则上)有一种方法可以做一些稍微不同的事情。我同意,当数据很大时,第一种方法不是一个好主意-这就是为什么提供了另一种方法。但这实际上取决于不会成为问题的少量数据的情况。您正在浪费内存空间(32位整数x n个记录)。您还应该看看这段代码中的另一幅图——调用ToList()会占用更多内存。在理想的代码中,您应该只使用IEnumerable进行流式处理,而不调用ToList()。如命名“ResponseDto”
var turstatus = turstatus();
var totalCount = turStatus.Select(x => x.Item2).Sum(); // assuming the first (tuple-based) approach)
var totalCount = turStatus.Select(x => x.Value).Sum(); // this is for the dictionary-based approach
// signature of the function would be like this:
int GetTurbineNumbers( out IEnumerable<TurbineStatus> ) // again: reconsider that class
// the other way round
IEnumerable<TurbineStatus> GetTurbineNumbers( out int totalTurbines )
class TurbineStatistics{
public IEnumerable<TurbineStatus> {get; set;}
public int Total {get; set;}
}
(IEnumerable<TurbineStatus>, int) GetTurbineNumbers()
IDictionary<string, int> GetTurbineNumbers()
{
// fill a dictionary with statusname, count and "total", count
// return it
}
public IEnumerable<TurbineStatus> turStatus()
{
int totalCount = _db.masterData.Select(s=>s.turbine_name).Count();
var result1 = (from s in _db.masterData
group s by s.current_turbine_status into g
select new TurbineStatus
{
status = g.Key,
numberOfTurbines = g.Count(),
total = totalCount,
}
).ToList().OrderByDescending(s => s.status);
return result;
}
public class ResponseDto {
IEnumerable<TurbineStatus> GroupData {get;set;}
int TotalCount {get;set;}
}
...
public ResponseDto turStatus()
{
int totalCount = _db.masterData.Select(s=>s.turbine_name).Count();
var result1 = (from s in _db.masterData
group s by s.current_turbine_status into g
select new TurbineStatus
{
status = g.Key,
numberOfTurbines = g.Count(),
}
).ToList().OrderByDescending(s => s.status);
return new ResponseDto(){
GroupData = result1,
TotalCount = totalCount
};
}
public ResponseDto turStatus()
{
var result1 = (from s in _db.masterData
group s by s.current_turbine_status into g
select new TurbineStatus
{
status = g.Key,
numberOfTurbines = g.Count(),
}
).ToList().OrderByDescending(s => s.status);
return new ResponseDto(){
GroupData = result1,
TotalCount = result1.Sum(t=> t.numberOfTurbines)
};
}