Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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
Entity framework 如果没有if语句(SUM/AVG),我如何实现下面的查询?_Entity Framework_Linq_Design Patterns_Group By_Linq Expressions - Fatal编程技术网

Entity framework 如果没有if语句(SUM/AVG),我如何实现下面的查询?

Entity framework 如果没有if语句(SUM/AVG),我如何实现下面的查询?,entity-framework,linq,design-patterns,group-by,linq-expressions,Entity Framework,Linq,Design Patterns,Group By,Linq Expressions,我正在使用IOC容器创建DailyAggreator/monthlyaggregator等实例。。。 但我无法通过表达式构建这个组,也无法应用正确的设计模式来消除上面的if语句 编译和调用函数来自LinqKit扩展。 使用此聚合器的类正在查询数据库并收集呼叫中心报告的数据,例如TotalCdrRecords报告、ReachedCdrRecords报告、CdrTalkTime报告、CdrCallAfterworkTime报告等,CDR是一个呼叫数据记录,实际上保存了关于呼叫的所有信息。查询T的类型

我正在使用IOC容器创建DailyAggreator/monthlyaggregator等实例。。。 但我无法通过表达式构建这个组,也无法应用正确的设计模式来消除上面的if语句

编译和调用函数来自LinqKit扩展。 使用此聚合器的类正在查询数据库并收集呼叫中心报告的数据,例如TotalCdrRecords报告、ReachedCdrRecords报告、CdrTalkTime报告、CdrCallAfterworkTime报告等,CDR是一个呼叫数据记录,实际上保存了关于呼叫的所有信息。查询T的类型在报表类中指定,但基本上是一个IReportableEntity,但operationProperty当然可以是DB实体的任何属性,我们可以执行count/sum/avg操作,groupByProperty始终是一个DateTime列

它生成以下sql查询:

public class DailyAggregator : Aggregator
{
    public override Dictionary<string, int?> Aggregate<T>(IQueryable<T> query, Expression<Func<T, DateTime>> groupByProperty, Expression<Func<T, double>> operationProperty = null)
    {
        if (operationProperty == null) // property of sum/avg (null = count)
            operationProperty = x => 1;

        if (_operationType.Equals(ReportAggregationOperation.Sum))
        {
            return query
                .GroupBy(g => new
                {
                    Day = TestableDbFunctions.TruncateTime(groupByProperty.Invoke(g))
                })
                .Select(x => new
                {
                    Key = x.Key.Day.ToString().Substring(0, 10),
                    Value = (int?) x.Sum(operationProperty.Compile()),
                })
                .ToDictionary(t => t.Key, t => t.Value);
        }
        else
        {
            return query
               .GroupBy(g => new
               {
                   Day = DbFunctions.TruncateTime(groupByProperty.Invoke(g))
               })
               .Select(
                x => new
                {
                    Key = x.Key.Day.ToString().Substring(0, 10),
                    Value = (int?) x.Average(operationProperty.Compile()),
                }).ToDictionary(t => t.Key, t => t.Value);
        }
    }
}

因为您使用的是LINQKit,所以可以提取一个用于调用求和/平均部分的表达式,并在查询中调用它

例如:

SELECT 
1 AS [C1], 
SUBSTRING(CASE WHEN ([GroupBy1].[K1] IS NULL) THEN N'' ELSE  CAST( [GroupBy1].[K1] AS nvarchar(max)) END, 0 + 1, 10) AS [C2], 
 CAST( [GroupBy1].[A1] AS int) AS [C3]
FROM ( SELECT 
    [Filter1].[K1] AS [K1], 
    SUM([Filter1].[A1]) AS [A1]
    FROM ( SELECT 
        convert (datetime2, convert(varchar(255), [Extent1].[CreatedOn], 102) ,  102) AS [K1], 
        cast(1 as float(53)) AS [A1]
        FROM [dbo].[VCCCdr] AS [Extent1]
        WHERE ([Extent1].[CreatedOn] >= @p__linq__0) AND ([Extent1].[CreatedOn] <= @p__linq__1) AND ([Extent1].[CompanyId] = @p__linq__2)
    )  AS [Filter1]
    GROUP BY [K1]
)  AS [GroupBy1]

出于好奇,它在所有的工作方式,它的书面?但是从建设性的角度来看,为了得到有意义的答案,有太多的信息缺失——查询类型、groupBy、operationProperty变量、调用和编译LINQKit的使用?等等。是的,除了tostring部分,它还能工作,但我编辑了这篇文章。是的,编译和调用是LinqKit的一部分。工作起来很有魅力:非常感谢!我希望这将对其他人有用,因为我没有发现关于通过表达式提取组的一部分的类似问题
var aggregateFunc = _operationType.Equals(ReportAggregationOperation.Sum) ?
        Linq.Expr((IEnumerable<double> source) => source.Sum()) :
        Linq.Expr((IEnumerable<double> source) => source.Average());

return query
    .GroupBy(g => new
    {
        Day = DbFunctions.TruncateTime(groupByProperty.Invoke(g))
    })
    .Select(x => new
    {
        Key = x.Key.Day.ToString().Substring(0, 10),
        Value = (int?)aggregateFunc.Invoke(x.Select(operationProperty.Compile())),
    })
    .ToDictionary(t => t.Key, t => t.Value);