错误 - 使用Linq时计算百分比

时间:2016-11-14 10:37:14

标签: c# linq

我有一个计算百分比的Ling查询。

        var total = db.Schema_Details.Where(x => x.RID == sName).Select(x => new{
Rid = x.RID,
Amount = Convert.ToDouble(x.Lum_Sum_Amount),
Allocation = Convert.ToDouble(x.Allocation),
total = ((x.Allocation / 100) * x.Lum_Sum_Amount)}).ToList(); 

但发生了异常。

enter image description here

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

由于您使用标识符db,我假设db是DbContext。这意味着您的linq语句将在数据库服务器端的SQL中执行,而不是在您的内存中执行(SQL或类似的东西,具体取决于您使用的数据库类型)。

如果在调试器中检查语句的类型,可以看到这个:是IQueryable还是IEnumerable? IQueryables由数据库服务器执行,IEnumerable通常在您的内存中执行。通常,您的数据库服务器可以比您更快,更高效地执行linq语句,因此最好确保您的linq语句是IQueryable。

但是,缺点是,您的数据库服务器不知道您的任何类,函数或.NET。因此,在IQueryables中,您只能使用相当简单的计算。

如果你真的需要在linq语句的中间某处调用一些本地函数,请在语句中添加AsEnumerable()

var myLinqResult = db. ...      // something IQueryable
    .Where(item => ... )        // simple statement: still IQueryable
    .Select(item => ...)        // still simple, still IQueryable
    // now you want to call one of your own functions:
    .AsEnumerable()
    .Select(item => myOwnLocalFunctions(item));

请参阅stackoverflow: Difference between IQueryable and IEnumerable

您要执行的本地功能是Convert.ToDouble。 IQueryable不知道Convert类,因此不能将您的函数作为IQueryable执行。 AsEnumerable将解决此问题。

但是,在这种情况下,我不建议使用AsEnumerable。在数据库上执行linq语句时尽量避免使用本地类和函数调用。而不是Convert.ToDouble使用(double)x.Sum_Amount。你的linq-to-sql翻译器(或类似的数据库语言转换器)将知道如何将其翻译为IQueryable。

有一些计算存在SQL等价物,如DateTime计算或字符串反转。如果你必须在本地内存中执行DateTime.AddDays(1)这样的事情,而对它有完美的SQL等价物,那将是一种耻辱。如果您需要在本地功能之后加入,选择或GroupBy,这将特别成问题。您的数据库服务器可以比您更有效地完成这些工作。幸运的是,它们有一些IQueryable扩展功能。它们可以在System.Data.Entity.DbFunctions

中找到