Last() 方法不适用于 IQueryable 对象

发布于 2024-09-14 01:54:53 字数 1082 浏览 8 评论 0原文

我对 C# 还很陌生,所以我可能会做一些愚蠢的事情,但我花了一些时间研究这个,但仍然看不出问题是什么。

以下是一些代码片段:

        double work = 0;
        ProjectRepository pr = new ProjectRepository();
        IQueryable<CalendarDetail> cds;

        // Find matching day of week
        // Then for that day, cycle through all working times

        // Return list of working times in day
        cds = pr.GetCalDetails(calendarID, startTime.DayOfWeek.GetHashCode());

        foreach (CalendarDetail cd in cds)
        {
            DateTime wts = startTime.Date + cd.WorkingTimeStart.Value.TimeOfDay;
            DateTime wtf = startTime.Date + cd.WorkingTimeFinish.Value.TimeOfDay;

            //more code here....

           if ((cds.Last().CalendarDetailID == cd.CalendarDetailID) && (finishTime > wtf))
                work += Work(startTime.Date.AddDays(1), finishTime, calendarID);
         }

由于我使用 cds.Last() 方法调用,因此在运行时引发错误。但是,cds 已被声明并被用作 IQueryable 对象,那么问题出在哪里呢?

错误文本: 不支持查询运算符“Last”。

如果解决方案失败,我确信我可以用“逻辑”解决问题,但这看起来很优雅。

谢谢,

乔纳森

I'm pretty new still at C# so I might be doing something stupid, but I've spent some time looking at this and still can't see what the problem is.

Here are some code snippets:

        double work = 0;
        ProjectRepository pr = new ProjectRepository();
        IQueryable<CalendarDetail> cds;

        // Find matching day of week
        // Then for that day, cycle through all working times

        // Return list of working times in day
        cds = pr.GetCalDetails(calendarID, startTime.DayOfWeek.GetHashCode());

        foreach (CalendarDetail cd in cds)
        {
            DateTime wts = startTime.Date + cd.WorkingTimeStart.Value.TimeOfDay;
            DateTime wtf = startTime.Date + cd.WorkingTimeFinish.Value.TimeOfDay;

            //more code here....

           if ((cds.Last().CalendarDetailID == cd.CalendarDetailID) && (finishTime > wtf))
                work += Work(startTime.Date.AddDays(1), finishTime, calendarID);
         }

The error is being thrown run-time due to my use of the cds.Last() method call. However, cds has been declared and is being used as an IQueryable object, so what is the problem?

Error text:
The query operator 'Last' is not supported.

Failing a solution I'm sure I can 'logic' my way around the problem, but this seemed elegant.

Thanks,

Jonathan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

梦归所梦 2024-09-21 01:54:53

答案是并非所有 IQueryable 提供程序都支持所有 Linq 方法。具有 SQL 后端的 IQeuryable 提供程序(例如 LinqToSql 或实体框架)不支持 Last(),因为 SQL 本身没有 Last 的概念。 Last() 没有要翻译成的 SQL 语句。

在 SQL 中,正确的方法是对记录进行适当的排序(也许通过 Id 描述),然后执行 Top 1。这就是我们需要在 Linq 中执行的操作:

CalendarDetail lastCd = cds.OrderByDescending(cd => cd.CalendarDetailId).First();

The answer is that not all IQueryable providers support all the Linq methods. IQeuryable providers with a SQL back-end, such as LinqToSql or Entity Framework don't support Last() because SQL itself doesn't have a concept of Last. There is no SQL statement for Last() to be translated into.

In SQL, the correct approach is to order the records appropriately (by Id Desc, perhaps) and then do Top 1. So that's what we need to do in Linq:

CalendarDetail lastCd = cds.OrderByDescending(cd => cd.CalendarDetailId).First();
终止放荡 2024-09-21 01:54:53

我认为这个问题没有足够的细节来回答它,因为您没有指出异常实际上是什么。

可能值得将对 .Last() 的调用替换为 .AsEnumerable().Last(),因为这将表明问题是否出在 Last() 上,或者是否出在查询中的其他位置。

.AsEnumerable().Last() 可能会更慢并且不能更快,因此如果您可以避免它,一般来说不值得这样做,但是(A)也许您不能,因为查询提供程序中的一些限制和(B)尝试的结果并查看是否遇到相同的异常将告诉您有关问题的更多信息。

I don't think there's enough detail in this question to answer it, because you don't indicate what the exception actually was.

It might be worth replacing the call to .Last() to .AsEnumerable().Last(), as this would indicate whether the problem was with Last() at all, or if it was elsewhere in the query.

.AsEnumerable().Last() can be slower and can't be faster so it's not worth doing generally if you can avoid it, but (A) maybe you can't because of some limitation in the query provider and (B) the result of trying it and seeing if you get the same exception will tell you more about your problem.

兲鉂ぱ嘚淚 2024-09-21 01:54:53

看起来 Linq 不支持 IQueryable 中的 Last()。你可以这样做:

List<CalendarDetail> cds;

    // Find matching day of week
    // Then for that day, cycle through all working times

    // Return list of working times in day
    cds = pr.GetCalDetails(calendarID, startTime.DayOfWeek.GetHashCode()).ToList();

It looks like Linq does not support Last() in IQueryable. You can do this:

List<CalendarDetail> cds;

    // Find matching day of week
    // Then for that day, cycle through all working times

    // Return list of working times in day
    cds = pr.GetCalDetails(calendarID, startTime.DayOfWeek.GetHashCode()).ToList();
彻夜缠绵 2024-09-21 01:54:53

如果不知道抛出的异常,很难猜测原因
但你实际上可以在 linq 中完成这一切,所以我认为这对你来说可能是有价值的信息

var lastID = cds.Last().CalendarDetailID;
var work =  (from cd in cds
            let wts = startTime.Date + cd.WorkingTimeStart.Value.TimeOfDay
            let wtf = startTime.Date + cd.WorkingTimeFinish.Value.TimeOfDay
            where (lastID == cd.CalendarDetailID) && (finishTime > wtf)
            select Work(startTime.Date.AddDays(1), finishTime, calendarID)).Sum();

(假设工作可以隐式转换为 .Sum() 可以处理的东西。即 += 不是自定义运算符)

It's hard to guess at the cause with out knowing the exception you're thrown
but you can actually do it all in linq so I thought that might be valuable information for you

var lastID = cds.Last().CalendarDetailID;
var work =  (from cd in cds
            let wts = startTime.Date + cd.WorkingTimeStart.Value.TimeOfDay
            let wtf = startTime.Date + cd.WorkingTimeFinish.Value.TimeOfDay
            where (lastID == cd.CalendarDetailID) && (finishTime > wtf)
            select Work(startTime.Date.AddDays(1), finishTime, calendarID)).Sum();

(on the assumption that work can be implicitly converted to something that .Sum() can handle. I.e. that += is not a custom operator)

山川志 2024-09-21 01:54:53

您需要告诉我们错误/异常是什么才能正确提供帮助,但 Last() 失败的最常见原因是 IQeryable 提供程序不支持它。例如我不认为 LinqToSQL 支持 Last()

You need to tell us what the error/exception is to help properly but the most common cause for Last() to fail is that the IQeryable provider does not support it. e.g. I don't think LinqToSQL supports Last()

老子叫无熙 2024-09-21 01:54:53

如果您的 CalendarDetailID 运行数字,您可以使用 Max()

if your CalendarDetailID is running numeric, you could use Max()

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文