Linq查询获取最后一条记录。

4

我知道这个问题被问了很多次,我在网上搜索了大部分的解决方案,但是似乎没有一个适合我的。我有一个这样结构的表格:

ID | ScheduleId | Filename | Description
 1 |     10     |          |  ....
 2 |     10     | test.txt |  .....

我希望通过传递ScheduleId(例如,在此情况下获取“test.txt”)来获取最后一个非空的文件名

我已经尝试了很多方法,但似乎没有得到文件名。以下是最后一个尝试:

var tempFileName = objContext.SchedulesAndFiles
                           .Where(x => x.ScheduleId == scheduleId)
                           .OrderByDescending(x => x.ScheduleId)
                           .Take(1).Select(x => x.Filename);

这种方法并不是很有效,尽管我知道它为什么无法实现:

var tempFileName = from e in objContext.SchedulesAndFiles
                   where e.ScheduleId == scheduleId 
                   orderby e.ScheduleId descending
                   select e.Filename;

调用.Last().LastOrDefault()会抛出异常(The query operator 'LastOrDefault' is not supported.)


在你的第一个例子中,你使用OrderByDescendingScheduleId进行排序。不应该使用ID吗?另外,你在哪里筛选出空的FileName记录? - Daniel Kelley
你只需要使用 tempFileName.First,因为你已经在使用 descending - Tim Schmelter
应支持First(),您可以将其与OrderByDescending一起使用。 - Davio
1
你正在按ScheduleId排序,但是你的示例中包含了两条具有相同ScheduleId的记录。所以显然你应该包括另一列作为排序依据,例如ID:... orderby e.ScheduleId descending, ID descending - Tim Schmelter
是的,你说得对,我已经接受了Selman22的答案,因为他建议的方法似乎正好给我带来了期望的结果。 - Apostrofix
5个回答

11

如果必须包含您只想要非空文件名的内容。您还可以使用 ToList() 完成查询,然后 FirstOrDefault() 应该按预期工作,请尝试。

var tempFileName = objContext.SchedulesAndFiles
                             .Where(x 
                                 => x.ScheduleId == scheduleId 
                                 && x.Filename != null 
                                 && x.Filename != "")
                             .OrderByDescending(x => x.ScheduleId)
                             .Take(1)
                             .Select(x => x.Filename)
                             .ToList()
                             .FirstOrDefault();

9

您应该根据ID而不是ScheduleId对记录进行排序,并过滤掉文件名为空的记录:

objContext.SchedulesAndFiles
          .Where(x => x.ScheduleId == scheduleId && x.Filename != "")
          .OrderByDescending(x => x.ID)
          .First().Filename;

2
如果未找到任何内容,这将抛出异常。 - esskar

3

其中一个选项是在使用 LastOrDefault() 之前调用 ToList() 或 AsEnumerable()。

var tempFileName = objContext.SchedulesAndFiles
                   .Where(x => x.ScheduleId == scheduleId 
                            && x.Filename != null && x.Filename != '')
                   .ToList().LastOrDefault();
if(tempFileName != null)
{
    // Do something
}

0
你可以尝试这个查询。我认为在选择文件名之前,你必须发出最后或默认的命令。
 var tempFileName = objContext.SchedulesAndFiles
                               .Where(x => x.ScheduleId == scheduleId && ! string.IsNullOrEmpty(e.FileName))
                               .FirstOrDefault().Select(x => x.Filename);

0

最后一次尝试:

var tempFileName = objContext.SchedulesAndFiles
                         .Where(x 
                             => x.ScheduleId == scheduleId 
                             && x.Filename != null 
                             && x.Filename != "")
                         .OrderByDescending(x => x.ID)
                         .First()
                         .Select(x => x.Filename);

对于具有此scheduleId的每个项目,获取所有具有非空fileName的项目,按ID降序排序(假设较高的ID在较低的ID之后插入),获取First()(应受支持)并获取其FileName。

请注意,如果没有满足条件的fileName,则可能会在First()上遇到NullPointerException。

此外,您可能需要进行规范化/修剪以避免找到空格/制表符等内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接