提问人:Hadi Bawarshi 提问时间:10/18/2023 最后编辑:marc_sHadi Bawarshi 更新时间:10/18/2023 访问量:57
ASP.NET Core 6 C# 根据 CreatedDate(DateTime) 对每日、每月、每年的数据进行分组,导致:无法转换 LINQ 表达式
ASP.NET Core 6 C# Grouping Data Daily ,Monthly ,Yearly based on CreatedDate(DateTime) causing : The LINQ expression could not be translated
问:
我有一种方法可以从SQL Server数据库中获取数据,并每天,每月和每年对其进行分组。
我们目前正在处理至少 3k 条记录,并且这个数字每天都会根据销售额增加。
我正在尝试获取数据并在数据库上执行分组依据,因为在服务器内存上执行GroupBy目前可能很好,但后来效率会大大降低,但是每次尝试时,我都会收到此错误:
LINQ 表达式 'DbSet()\r\n.LeftJoin(\r\ninner: DbSet(), \r\n outerKeySelector: b => EF.Property<int?>(b, “CreatedByBusinessCrewId”), \r\n innerKeySelector: b0 => EF.Property<int?>(b0, “Id”), \r\n resultSelector: (o, i) => new TransparentIdentifier<BusinessSale, BusinessCrew>(\r\n Outer = o, \r\n Inner = i\r\n ))\r\n .其中(b => b.Outer.BusinessId == __BusinessId_0 && b.Inner.BranchId == __BranchId_1)\r\n .GroupBy(b => Invoke(__dateTruncateFunction_2, b.Outer.CreateDate.Value)\r\n )' 无法翻译。以可翻译的形式重写查询,或者通过插入对“AsEnumerable”、“AsAsyncEnumerable”、“ToList”或“ToListAsync”的调用来显式切换到客户端评估。有关详细信息,请参阅 https://go.microsoft.com/fwlink/?linkid=2101038。
这是我的枚举
public enum BusinessSalesFilteredBy
{
Logs = 0,
Day = 1,
Month = 2,
Year = 3,
}
请注意,我使用的是工作单元。
这是我的代码:
var baseQuery = _uow.BusinessSalesRepo.GetAll(sale => sale.BusinessId == BusinessId && sale.CreatedByBusinessCrew.BranchId == BranchId);
salesCount = baseQuery.Count();
clientsCount = baseQuery.Select(s=> s.ClientProfileId).Distinct().Count();
sumPurchases = baseQuery.Sum(s=> s.PurchasedAmount ?? 0);
Func<DateTime, DateTime> dateTruncateFunction;
switch (filterBy)
{
case (int)BusinessSalesFilteredBy.Day:
groupKeySelector = sale=> sale.CreateDate.Value.Date;
break;
case (int)BusinessSalesFilteredBy.Month:
groupKeySelector = sale=> new DateTime(sale.CreateDate.Value.Year, checkin.CreateDate.Value.Month, 1);
break;
case (int)BusinessSalesFilteredBy.Year:
groupKeySelector = sale=> new DateTime(sale.CreateDate.Value.Year, 1, 1);
break;
default:
// Default to daily grouping
groupKeySelector = sale=> sale.CreateDate.Value.Date;
break;
}
// Now, calculate the summary data with date truncation
var summaryQuery = baseQuery
.GroupBy(sale=> dateTruncateFunction(sale.CreateDate.Value))
.Select(grouped => new
{
SalesOn = grouped.Key,
SalesCount = grouped.Count(),
ClientCount = grouped.Select(x => x.ClientProfileId).Distinct().Count(),
SumPurchases = grouped.Sum(x => x.PurchasedAmount ?? 0)
});
var pagedSummary = await summaryQuery.ToListAsync();
最后是方法:GetAll()
public IQueryable<T> GetAll(Expression<Func<T, bool>> predicate)
{
return GetAll().Where(predicate);
}
public IQueryable<T> GetAll()
{
return _context.Set<T>().AsNoTracking();
}
我的问题是如何在不将数据带入内存的情况下在数据库端执行整个操作,希望找到最有效的方法。
在LINQ查询中,是否没有内置的东西可以帮助进行DateTime转换?
答:
你必须使用才能使事情在服务器端工作。已添加,不确定 EF 将如何将其视为分组键。Expression<Func<,>>
DateGroupingKey
DateTime
class DateGroupingKey
{
public int Year [ get; set; ]
public int Month [ get; set; ]
public int Day [ get; set; ]
}
var baseQuery = _uow.BusinessSalesRepo
.GetAll(sale => sale.BusinessId == BusinessId && sale.CreatedByBusinessCrew.BranchId == BranchId);
Expression<Func<DateTime, DateGroupingKey>> groupKeySelector;
switch (filterBy)
{
case (int)BusinessSalesFilteredBy.Month:
groupKeySelector = sale => new DateGroupingKey {
Year = sale.CreateDate.Value.Year, Month = sale.CreateDate.Value.Month
}
break;
case (int)BusinessSalesFilteredBy.Year:
groupKeySelector = sale => new DateGroupingKey {
Year = sale.CreateDate.Value.Year
}
break;
default:
// Default to daily grouping
groupKeySelector = sale => new DateGroupingKey {
Year = sale.CreateDate.Value.Year, Month = sale.CreateDate.Value.Month, Day = sale.CreateDate.Value.Day
}
break;
}
ar summaryQuery = baseQuery
.GroupBy(groupKeySelector)
.Select(grouped => new
{
SalesOn = grouped.Key,
SalesCount = grouped.Count(),
ClientCount = grouped.Select(x => x.ClientProfileId).Distinct().Count(),
SumPurchases = grouped.Sum(x => x.PurchasedAmount ?? 0)
});
var pagedSummary = await summaryQuery.ToListAsync();
评论
Expression
Func
sale.CreatedDate.Value.Date
new DateTime(sale.CreatedDate.Value.Year, sale.CreatedDate.Value.Month, sale.CreatedDate.Value.Day)
评论