我有一个
StudentReceipts
表,它存储ReceiptNo
作为string(001,002,003,..,099,..)
。
我想获取最后一张收据的详细信息,以便为下一次交易增加收据。
这是我试过的
var _lastGeneratedRecDetails = _db.StudentReceipts
.AsEnumerable()
.Where(r => r.Status == true
&& EntityFunctions.TruncateTime(r.DueDate.Value) >= _startDate.Date
&& EntityFunctions.TruncateTime(r.DueDate.Value) <= _endDate.Date)
.OrderByDescending(x => Int32.Parse(x.ReceiptNo))
.FirstOrDefault();
但是我得到以下异常
此函数只能从 linq to entities 调用
任何帮助将不胜感激。
通过调用
.AsEnumerable()
,您将从 Linq-To-Entities 转到 Linq-To-Object。通过调用它,您还过滤了内存中的所有结果,因此每次执行该查询时,您都会从数据库中提取整个 StudentReceipts
表,因为它通过 .AsEnumerable()
方法执行。一般规则是尽可能多地在数据库方面做:
var _lastGeneratedRecDetails =
_db.StudentReceipts.Where(r => r.Status == true
&& EntityFunctions.TruncateTime(r.DueDate.Value) >= _startDate.Date
&& EntityFunctions.TruncateTime(r.DueDate.Value) <= _endDate.Date)
.AsEnumerable()
.OrderByDescending(x => Int32.Parse(x.ReceiptNo))
.FirstOrDefault();
如果你这样做,你将过滤数据库中的所有内容并获取过滤后的结果。我不知道
x.ReceiptNo
是什么类型,但是在 Linq-To-Entities 中不允许调用 Int.Parse
。您可以先过滤,然后调用AsEnumerable
,以便能够在内存中进行解析和排序。
就我而言,在我已经用 SQL 处理了查询之后,我在后续处理语句中重新使用了包含 DbFunctions.TruncateTime 的 Func / Filter 表达式。删除它为我清除了异常实例。
使用和
.AsQueryable()
var _lastGeneratedRecDetails = _db.StudentReceipts
.AsEnumerable().AsQueryable()
我想知道为什么会出现这个错误,我记得有些 DbFunctions 工作得很好。 原因是,并非所有 DbFunctions 都是在 C# 代码中实现的!
如果你看一下
TruncateTime
[DbFunction("Edm", "TruncateTime")]
public static DateTime? TruncateTime(DateTime? dateValue)
{
throw new NotSupportedException(Strings.ELinq_DbFunctionDirectCall);
}
你可以看到为什么会抛出这个错误。它只是没有实现。
上面的代码基本上说:如果在 LINQ to Entities 中使用,则执行 SQL 函数
TruncateTime
,如果在 LINQ to Objects 中使用,则运行代码(在本例中:抛出异常)
您可以实现自己的方法,只需将上面的代码复制到您自己的类中,并将您的
DbFunctions.TruncateTime(.)
调用替换为MyFunctions.TruncateTime(.)
这真的很烦人。我需要这个,因为有时查询会针对数据库运行,有时只在代码中运行..
当然,如果您只需要对数据库调用该函数,您完全可以使用上述解决方案