Linq sum由月份S或周S的可变数量组成

agg*_*gie 0 c# linq sql-server entity-framework

SqlServer表包含烧毁的时间和小时的记录,供应商的材料成本

  • [IdPK] [DateTime] [MaterialsCost] [小时] [Vendor_FK] [Project_FK] [Lat] [长]

用户决定他想要查看总数的 多长时间以及 哪个列值,即他希望总计返回 - 在任何columns_FK过滤器值上的X个月份数或者 X个周数.

例如,他要求总成本,小时数,供应商=耐克或ProjectX,从某个日期开始(1)月,(3)周或2个月.所以,我试图根据参数化的Linq查询得到总数.

问题:

  1. 使用任何列在LINQ过滤器/选择器,如何获取成本每月/每周总计,小时 -要回一个月(X)号小号或一周小号
  2. 另外,我应该针对几个月和几周编写单独的查询,并为每个列分别查询(用户选择的列值,作为genric val传递给我)?

     // I tried this... but just stuck
     DateTime now = DateTime.Now;
     Int goBack = passedinGoingBack;  // amount of units to go back
     var backUnits = obj.GetType().GetProperty(name); // tried getting month or week??
     var getRows = table.AsEnumerable()
     var columnName = passedInColumnName;
     var filter = passedInValue;
    
    .Where(r =>  r.Field<DateTime>(columnName).Year  == now.Year
              && r.Field<DateTime>(columnName).Month == now.Month);
    
    Run Code Online (Sandbox Code Playgroud)

Yel*_*yev 5

这个问题有点基于意见.你可以用任何方便的方式做到这一点.我就是这样做的.

第一:Sum根据给定的求和规则,您可以使用LINQ函数获取总数.

var monthlyRows = table.AsEnumerable()
           .Where(r => r.Field<DateTime>("ColumnName").Year == now.Year 
                    && r.Field<DateTime>("ColumnName").Month == now.Month);

var monthlyTotalForCost = monthlyRows.Sum(r => r.Field<decimal>("CostColumn"));
var monthlyTotalForHours = monthlyRows.Sum(r => r.Field<decimal>("HoursColumn"));

var weeklyRows = table.AsEnumerable()
           .Where(r => r.Field<DateTime>("ColumnName").Year == now.Year 
                    && r.Field<DateTime>("ColumnName").Week == now.Week);

var weeklyTotalForCost = monthlyRows.Sum(r => r.Field<decimal>("CostColumn"));
var weeklyTotalForHours = monthlyRows.Sum(r => r.Field<decimal>("HoursColumn"));
Run Code Online (Sandbox Code Playgroud)

第二:我会对每周和每月总计进行单独查询,因为它是不同实体值的总和,并且可能存在不同的逻辑.

但是,我会像这样为我做一个帮助功能:

public static class TableLinqHelper
{
    public static SumOfTableColumn<T>(this IEnumerable<DataRow> rows, string columnName)
    {
        return rows.Sum(r => r.Field<T>(columnName));
    }

    public static DateTime GetDate(this DataRow row)
    {
        return row.Field<DateTime>("DateColumn");
    }

    public static GetTotalForCost(this IEnumerable<DataRow> row)
    {
        return SumOfTableColumn<decimal>(row, "CostColumn");
    }

    public static GetTotalForHours(this IEnumerable<DataRow> row)
    {
        return SumOfTableColumn<double>(row, "HoursColumn");
    }
}

var monthlyRows = table.AsEnumerable()
           .Where(r => r.GetTime().Year == now.Year 
                    && r.GetTime().Month == now.Month);
var weeklyRows = table.AsEnumerable()
           .Where(r => r.GetTime().Year == now.Year 
                    && r.GetTime().Week == now.Week);


var monthlyTotalForCost = monthlyRows.GetTotalForCost();
var monthlyTotalForHours = monthlyRows.GetTotalForHours();
var weeklyTotalForCost = weeklyRows.GetTotalForCost();
var weeklyTotalForHours = weeklyRows.GetTotalForHours();
Run Code Online (Sandbox Code Playgroud)

更新:

过滤:您可以使用WhereLINQ 过滤结果.

Dictionary<string, object> Filters = new Dictionary<string, object>();
Filters.Add("VendorColumn", "Nike");
Filters.Add("Hours", 7.0);

foreach (var filter in Filters)
{
   monthlyRows = monthlyRows.Where(r => // ...);
}
Run Code Online (Sandbox Code Playgroud)

几个月和几周:你可以改变DateTime的条件.

int rowsToBeShown = 4;
var monthlyRows = table.AsEnumerable()
    .Where(r => r.Field<DateTime>("ColumnName") > DateTime.Now.AddMonths(-rowsToBeShown));
Run Code Online (Sandbox Code Playgroud)

它将显示最后4个月的结果.

LINQ为数据操作提供了非常方便和灵活的工具.这完全取决于你的幻想.