Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.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# 如何附加两个linq查询的结果_C# - Fatal编程技术网

C# 如何附加两个linq查询的结果

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 {

我有两个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
                  {
                      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)
            };
        }