在LINQ to Entities查询中,不支持转换为十进制数。

12

我有一个数据库表Transaction (transactionID, LocalAmount...),其中Localamount属性的数据类型为float。在用户界面上,我尝试在点击按钮事件时返回一行中列(Localamount)的SUM

我已经使用decimal代替了float

然而,在我进行强制转换为decimal的代码中出现了错误。

System.NotSupportedException was unhandled by user code
Message=Casting to Decimal is not supported in LINQ to Entities queries, because the required precision and scale information cannot be inferred.

The

 public static IEnumerable<TransactionTotalForProfitcenter> GetTotalTransactionsForProfitcenter(int profitcenterID)
    {
        List<TransactionTotalForProfitcenter> transactions = new List<TransactionTotalForProfitcenter>();
        using (var context = new CostReportEntities())
        {
          transactions = (from t in context.Transactions
                            join comp in context.Companies on t.CompanyID equals comp.CompanyID
                            join c in context.Countries on comp.CountryID equals c.CountryID
                            where c.CountryID.Equals(comp.CountryID) && t.CompanyID == comp.CompanyID 
                             
                            join acc in context.Accounts
                                 on t.AccountID equals acc.AccountID
                            join pc in context.Profitcenters
                                on t.ProfitcenterID equals pc.ProfitcenterID
                            group t by pc.ProfitcenterCode into tProfitcenter
                            
                            select new TransactionTotalForProfitcenter
                            {
                                ProfitcenterCode = tProfitcenter.Key,
                    //the error is occurring on the following line           
                                TotalTransactionAmount = (decimal)tProfitcenter.Sum(t => t.LocalAmount),  
                   //the error is occurring on the following line       
                                TotalTransactionAmountInEUR = (decimal)tProfitcenter.Sum(t => t.AmountInEUR) //the error is occurring on this line 
                            }
                            ).ToList();

        }
        return transactions;

    }

我已经尝试了以下帖子中的一些选项,但都没有成功。

请问还有哪些其他选项可以尝试。如果我的 LINQ 知识太肤浅,请谅解。

4个回答

13

Entity Framework提示它不支持您所需的转换。一种解决方法是尽可能在数据库中执行大部分工作,然后在内存中完成进程。在您的情况下,您可以计算其本地类型的总和,将结果作为匿名类型拉入内存,然后在构造实际需要的类型时执行转换。要使用原始查询,您可以进行以下更改:

select new // anonymous type from DB
{
    ProfitcenterCode = tProfitcenter.Key,
    // notice there are no conversions for these sums
    TotalTransactionAmount = tProfitcenter.Sum(t => t.LocalAmount),       
    TotalTransactionAmountInEUR = tProfitcenter.Sum(t => t.AmountInEUR)
})
.AsEnumerable() // perform rest of work in memory
.Select(item =>
     // construct your proper type outside of DB
    new TransactionTotalForProfitcenter
    {
        ProfitcenterCode = item.ProfitcenterCode,
        TotalTransactionAmount = (decimal)item.TotalTransactionAmount
        TotalTransactionAmountInEUR = (decimal)item.TotalTransactionAmountInEUR
    }
).ToList();

问题是我最初在数据库中将数据类型设置为float (缺乏知识),然后更改为decimal(因为我遇到了格式问题)。然而,模型由EF从float自动生成为double。是否有好主意再次生成实体类来尝试这种解决方案? - PineCone
1
是的,理想情况下,您希望实体类与数据库类型一致。您似乎已经做出了明智的决定,将数据库类型更改为十进制,因为您正在处理财务金额(看起来是这样),并且让您的类以相同的方式处理它们会很好。这可能使上面写的查询成为无意义的点。 - Anthony Pegram
在其他情况下,这个“明智”的事情通常很难做,因为你可能已经积累了传统数据并拥有大量的传统代码,因此即使是合理的更改也变得具有风险。 - Anthony Pegram
我已经重新生成了模型,并将数据类型从double更改为decimal,你的解决方案完美地运行。非常感谢。 - PineCone
@AnthonyPegram 这不是我想要的意思。我经常处理非常复杂的查询。如果你正在使用任何类型的IQueryable,将许多其他iqueryables组合到其中一个可枚举对象中,那么将一个可枚举对象拉入其中就会否定基本上所有东西。我讨厌这种回答,因为它们无法解决所提出的问题。下面alp ates的答案是正确的回应。 - Philip Vaughn
显示剩余5条评论

7

如果您没有使用AsEnumerable的条件,那么可以通过一些数学计算将其转换为int,然后再转换为十进制。

 (((decimal)((int)(x.Discount * 10000))) / 10000)

每个零实际上代表转换将具有的精度。这个答案来自这里,只需查看文件末尾即可。

这是对OP问题的正确回答,因为它保持了所有内容的查询形式。 - Philip Vaughn

2
我建议您在查询完成后进行转换。
var somevar = (decimal)transactions.YourValue

但我只使用交易表中的两列,它们是LocalAmount和AmountInEUR,在数据库中为Float,但在ViewModel类中为decimal。而且需要使用.ToList()将交易转换,因为该方法返回List<>。在这种情况下,我能否实际应用您的建议?我不太明白该如何做。 - PineCone

1
有时需要进行类型转换,如果超过两位小数。
     double TotalQty;
     double.TryParse(sequence.Sum(x => x.Field<decimal>("itemQty")).ToString(),out TotalQty);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接