问题 LINQ to Entities查询不支持强制转换为Decimal


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

我用过 十进制 代替 浮动

但是我在我要转换的代码上收到错误 十进制 

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的一点知识,如果它太琐碎了。


7673
2018-02-18 15:41


起源



答案:


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

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

12
2018-02-18 16:11



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


答案:


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

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

12
2018-02-18 16:11



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


我建议你在查询结束后进行演员表

var somevar = (decimal)transactions.YourValue

1
2018-02-18 15:48



但我只是使用事务表中的两列,即LocalAmount和AmountInEUR,它们在数据库中是Float,但在ViewModel类中是十进制的。并且需要使用.ToList()转换事务,因为该方法返回List <>。在这种情况下,我可以实际应用您的建议吗?我不太明白我该怎么做。 - shaz


有时需要施放,如果超过两个十进制宫殿

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

1
2018-01-21 07:19