【问题标题】:Casting to Decimal is not supported in LINQ to Entities queries在 LINQ to Entities 查询中不支持强制转换为十进制
【发布时间】:2013-02-18 15:41:34
【问题描述】:

我有一个数据库表 Transaction (transactionID, LocalAmount...)。其中 Localamount 属性的数据类型是 float。在 UI 上,我试图在按钮单击事件的一行中返回列 (Localamount) 的 SUM

我使用 decimal 而不是 float

但是,我在转换为 十进制

的代码上遇到错误
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.

 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 的了解太少。

【问题讨论】:

    标签: c# asp.net linq-to-sql casting decimal


    【解决方案1】:

    实体框架表明它不支持您想要的转换。一种解决方法是在数据库中尽可能多地执行工作,然后在内存中完成该过程。在您的情况下,您可以计算其本机类型的总和,将结果作为匿名类型拉入内存,然后在构造实际需要的类型时执行转换。要获取原始查询,您可以进行以下更改:

    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();
    

    【讨论】:

    • 这似乎可行,但我收到错误{“从物化 'System.Decimal' 类型到 'System.Double' 类型的指定转换无效。”}。这是因为 Transaction 的 Model 类包含我手动更改的 LocalAmount 和 AmountInEuro 属性的双精度,但随后它在概念侧类型“CostReportModel.Transaction”中给出了成员“LocalAmount”的类型“Edm.Double”的另一个错误与对象端类型“CostReportModel.Transaction”上成员“LocalAmount”的类型“System.Decimal”不匹配。
    • 遗憾的是,这些问题与此查询不同。您(或您团队中的某个人)似乎一直在玩弄您的实体,这可能很危险。您可能需要一个单独的问题,了解如何在实体数据模型中安全更改类型。
    • 问题是我首先在 DB 中设置了数据类型(缺乏知识),然后将它们更改为十进制(因为我遇到了格式问题)。但是,模型由 EF 自动生成,从 float 变为 double。再次生成实体类以尝试此解决方案是否是个好主意?
    • 是的,理想情况下,您希望您的实体类在类型上与您的数据库一致。由于您正在处理财务金额(出现),因此您似乎在将数据库类型更改为十进制方面做了明智的事情,并且您的班级以同样的方式对待它们会很好。这可能会使上面写的查询成为有争议的问题。
    • (*在其他情况下,这种“明智”的事情通常很难做到,因为您可能已经建立了遗留数据,并且拥有大量遗留代码,因此,即使是明智的更改也变得有风险。)
    【解决方案2】:

    如果您碰巧没有调用 AsEnumerable 的奢侈,那么您可以将其转换为int,而不是通过一些数学运算转换为十进制。

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

    每个零实际上代表转换将具有的精度。

    this 得到这个答案。只需看一下文件的末尾。

    【讨论】:

    • 这是对 OP 问题的正确回答,因为它将所有内容都保留在查询形式中。
    【解决方案3】:

    我建议您在查询完成后进行演员表

    var somevar = (decimal)transactions.YourValue
    

    【讨论】:

    • 但我只是使用事务表中的两列,它们是 LocalAmount 和 AmountInEUR,它们在数据库中是浮点数,但在 ViewModel 类中是十进制的。并且交易需要使用 .ToList() 进行转换,因为该方法返回 List。在这种情况下,我可以实际应用您的建议吗?我不太明白我该怎么做。
    【解决方案4】:

    如果多于两个小数宫,有时需要强制转换

         double TotalQty;
         double.TryParse(sequence.Sum(x => x.Field<decimal>("itemQty")).ToString(),out TotalQty);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-14
      • 2014-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多