C# LINQ按日期分组-包括不使用join的空天数

C# LINQ按日期分组-包括不使用join的空天数,c#,linq,nhibernate,join,linq-method-syntax,C#,Linq,Nhibernate,Join,Linq Method Syntax,使用C#,NHibernate,NHibernate到LINQ。使用NHibernate到LINQ,我没有连接功能。我也不能用QueryOver 我有一个LINQ查询,它统计潜在客户和销售额。此表仅在新潜在客户或销售完成时创建,因此某些天没有插入行。执行以下查询工作 var query3 = query2.AsEnumerable() .Where(x => x.Created <= toDate.Value && x.Created >=

使用C#,NHibernate,NHibernate到LINQ。使用NHibernate到LINQ,我没有连接功能。我也不能用QueryOver

我有一个LINQ查询,它统计潜在客户和销售额。此表仅在新潜在客户或销售完成时创建,因此某些天没有插入行。执行以下查询工作

var query3 = query2.AsEnumerable()
           .Where(x => x.Created <= toDate.Value && x.Created >= fromDate.Value)
           .GroupBy(x => x.Created.Date)
           .Select(g => new ReferrerChart {
               Date = g.Key.Date,
               LeadsCount = g.Count(x => !x.IsSale),
               SalesCount = g.Count(x => x.IsSale)
           });
var query3=query2.AsEnumerable()
.Where(x=>x.Created=fromDate.Value)
.GroupBy(x=>x.Created.Date)
.选择(g=>新建参考图表{
日期=g.Key.Date,
LeadsCount=g.Count(x=>!x.IsSale),
SalesCount=g.Count(x=>x.IsSale)
});
但有些日期不在其中(0个潜在客户和销售的日期)

如何在不使用join的情况下包含这些日期并让它们设置LeadsCount=0和SalesCount=0

编辑:

有效的最终结果:

var selectedFromDate = fromDate.Value;
var selectedToDate = toDate.Value;

var selectedDates = Enumerable.Range(0, 1 + selectedToDate.Subtract(selectedFromDate).Days)
          .Select(offset => new ReferrerChart { 
                            Date = selectedFromDate.AddDays(offset),
                            LeadsCount = 0,
                            SalesCount = 0
                            })
          .ToList();

var query3 = Find(x => x.Source == "UserRef").AsEnumerable()
             .Where(x => x.Created <= toDate.Value && x.Created >= fromDate.Value)
             .GroupBy(x => x.Created.Date)
             .Select(g => new ReferrerChart {
                 Date = g.Key.Date,
                 LeadsCount = g.Count(x => !x.IsSale),
                 SalesCount = g.Count(x => x.IsSale)
             }).ToList();

var result = query3.Union(
                        selectedDates
                        .Where(e => !query3.Select(x => x.Date).Contains(e.Date)))
                        .OrderBy(x => x.Date);
var selectedFromDate=fromDate.Value;
var selectedToDate=toDate.Value;
var selectedDates=可枚举的范围(0,1+selectedToDate.Subtract(selectedFromDate).Days)
.Select(offset=>newrefererchart{
日期=从Date.AddDays(偏移量)中选择,
LeadScont=0,
SalesCount=0
})
.ToList();
var query3=Find(x=>x.Source==“UserRef”).AsEnumerable()
.Where(x=>x.Created=fromDate.Value)
.GroupBy(x=>x.Created.Date)
.选择(g=>新建参考图表{
日期=g.Key.Date,
LeadsCount=g.Count(x=>!x.IsSale),
SalesCount=g.Count(x=>x.IsSale)
}).ToList();
var result=query3.Union(
选定的日期
.Where(e=>!query3.Select(x=>x.Date).Contains(e.Date)))
.OrderBy(x=>x.Date);

在您的LINQ查询中,我将更改两件事,包括空日期

。其中(x=>x.Created=fromDate.Value)

变得有点像

。其中(x=>x.Created.Date==null | |(x.Created=fromDate.Value))

我的另一个指针是,您的.GroupBy需要一个x.Created.Date,使用IsNull或类似函数将此处的值设置为一个值,而不管条目是否为Null

例如,
(x.Created==null?”:x.Created.ToString(“yyyyMMdd”)


(很抱歉,我现在不在我的开发PC上,因此无法确定正确的代码)

在您的LINQ查询中,我会更改两件事,包括空日期

。其中(x=>x.Created=fromDate.Value)

变得有点像

。其中(x=>x.Created.Date==null | |(x.Created=fromDate.Value))

我的另一个指针是,您的.GroupBy需要一个x.Created.Date,使用IsNull或类似函数将此处的值设置为一个值,而不管条目是否为Null

例如,
(x.Created==null?”:x.Created.ToString(“yyyyMMdd”)

(很抱歉,我现在不在我的开发PC上,因此无法确定正确的代码)

您可以
Union()
使用在内存中创建的虚拟项从查询中获取数据。例如:

var query4 = query3.ToList(); // Prevent multiple execution.

var startDate = DateTime.Today.AddDays(-99);

var emptyData = Enumerable.Range(1,100).Select (i => 
    new ReferrerChart
        {
           Date = startDate.AddDays(i),
           LeadsCount = 0,
           SalesCount = 0
        });

var result = query4 .Union(
             emptyData
                .Where(e => !query4.Select(x => x.Date).Contains(e.Date)))
             .OrderBy(x => x.Date);
您可以使用在内存中创建的伪项
Union()
查询中的数据。例如:

var query4 = query3.ToList(); // Prevent multiple execution.

var startDate = DateTime.Today.AddDays(-99);

var emptyData = Enumerable.Range(1,100).Select (i => 
    new ReferrerChart
        {
           Date = startDate.AddDays(i),
           LeadsCount = 0,
           SalesCount = 0
        });

var result = query4 .Union(
             emptyData
                .Where(e => !query4.Select(x => x.Date).Contains(e.Date)))
             .OrderBy(x => x.Date);

实现
IEnumerable
(从
GroupBy
返回的类型)的扩展方法是一种很好的方法。在我看来,这是最好的方法,原因有很多:

  • 不会重新计算正在填充的结果集(
    .ToList()
    也可以完成此操作,但代价是急于求值)
  • 保持
    GroupBy
    的延迟计算(延迟执行)
  • 一行程序友好(可以链接在流畅的LINQ查询中)
  • 通用的,可重复使用的
  • 优雅,易读
实施 样本输出 (顶部的五个整数是在计算查询时从查询内部打印出来的。如您所见,只有一个计算过程)


实现
IEnumerable
(从
GroupBy
返回的类型)的扩展方法是一种很好的方法。在我看来,这是最好的方法,原因有很多:

  • 不会重新计算正在填充的结果集(
    .ToList()
    也可以完成此操作,但代价是急于求值)
  • 保持
    GroupBy
    的延迟计算(延迟执行)
  • 一行程序友好(可以链接在流畅的LINQ查询中)
  • 通用的,可重复使用的
  • 优雅,易读
实施 样本输出 (顶部的五个整数是在计算查询时从查询内部打印出来的。如您所见,只有一个计算过程)


回答得真好!谢谢你,格特,回答得很好!谢谢你,格特。
Random rand = new Random();

var results = Enumerable.Repeat(0, 5)                    // Give us five
    .Select(i => rand.Next(100))                         // Random numbers 0 - 99
    .GroupBy(r => r.Dump("Calculating group for:") / 10) // Group by tens (0, 10, 20, 30, 40...)
    .Fill(Enumerable.Range(0, 10))                       // Fill aby missing tens
    .OrderBy(g => g.Key);                                // Sort

@"Anything above = eager evaluations.
Anything below = lazy evaluations.".Dump();

results.Dump();