Linq to Entities没有';t返回与foreach相同的值

本文关键字:foreach 返回 Entities to 没有 Linq | 更新日期: 2024-10-18 13:40:20

注意:我使用的是EF 6.1.2

我有一个交易数据库,将在特定日期提供。我有一个方法应该返回当前可用的余额,但当在EF中运行时,它返回的值与正常运行时不同。。。

我的实体类如下:

public class Transaction
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public int AmountInCents { get; set; }
    public DateTimeOffset DateAvailable { get; set; }
}

此方法返回正确的可用金额:

double GetAvailableBalance(DbProxy dbProxy, DateTimeOffset atTime)
{
    var amount = 0d;
    var transactions = dbProxy.Transactions.ToList();
    foreach (var transaction in transactions)
    {
        if (transaction.DateAvailable <= atTime)
        {
            amount += transaction.AmountInCents/100d;
        }
    }
}

此版本返回0:

double GetAvailableBalance(DbProxy dbProxy, DateTimeOffset atTime)
{
    return await dbProxy.Transactions
        .Where(t => t.DateAvailable <= atTime)
        .Select(t => t.AmountInCents / 100d)
        .Union(new[] { 0d })
        .SumAsync();
}

我很困惑为什么这不起作用。。。有人知道问题出在哪里吗?

Linq to Entities没有';t返回与foreach相同的值

与0的并集是导致此问题的原因。您应该将其更改为使用DefaultIfEmpty(),也可以使用Concat(new[] { 0 })

同样,我想强调的是,如果你处理的是美元金额,你可能应该使用decimal,否则你可能会遇到不稳定的数学运算,这可能会导致真金白银下落不明或丢失。

double GetAvailableBalance(DbProxy dbProxy, DateTimeOffset atTime)
{
    return await dbProxy.Transactions
        .Where(t => t.DateAvailable <= atTime)
        .Select(t => t.AmountInCents / 100d)
        .DefaultIfEmpty()
        .SumAsync();
}
double GetAvailableBalance(DbProxy dbProxy, DateTimeOffset atTime)
{
    return await dbProxy.Transactions
        .Where(t => t.DateAvailable <= atTime)
        .Select(t => t.AmountInCents / 100d)
        .Concat(new[] { 0 })
        .SumAsync();
}

如果你必须使用替身,你至少应该转换成替身作为最后一步:

    return await dbProxy.Transactions
        .Where(t => t.DateAvailable <= atTime)
        .Select(t => t.AmountInCents)
        .DefaultIfEmpty()
        .SumAsync() / 100d;