我想在下面的模型的最后一条记录上执行条件:
public partial class TestPart
{
public int Id { get; set; }
public int TestId { get; set; }
public int Status { get; set; }
public virtual ICollection<Job> Jobs { get; set; }
}
查询:
var query = context.TestPart.OrderByDescending(tp=>tp.Id)
.Take(1)
.Where(tp => tp.TestId == 100 &&
tp.Status == 1 &&
tp.Jobs.All(j => j.Type == "Recurring")
在这里,我希望获得status = 1 and all jobs are recurring
的TestPart的ID,但这应该只考虑checking last record of test part
但我无法在上述查询中选择上一个TestPart的ID。
更新:
Id TestId Status
1 100 1
2 100 2
3 100 0
4 100 1
5 101 1
所以这里我想基于TestId筛选出数据,然后选择该特定TEST的最后一条记录,然后检查所有作业类型是否为最后选择的TestPart id重复出现,即上面的情况TestPartId = 4。
答案 0 :(得分:3)
解释有点支离破碎。为了确保我正在回答正确的问题,这些是我的假设:
Test
有许多TestPart
个孩子。TestPart
,而不仅仅是表格的最后一个条目(无论测试ID)。您需要在此处拆分数据检索和数据验证步骤。
合并它们时,会得到不同的结果。您要求最后一个符合条件的项目。这意味着在10个项目(按时间顺序编号为1到10)的列表中,如果符合条件并且9和10不符合标准,则最终可能会获得项目 8 。
根据你的描述,我猜测那不是你想要的。您想要使用 10 项目(无论其是否符合条件,仅>检查此项目是否符合条件。
这样想:
- 我想要最后一个名叫John的人进入这座建筑。
- 我想知道进入大楼的最后一个人是否被命名为John。
您的代码正在尝试先执行此操作。但你真正想要的是第二个。
您的代码的正确版本:
//Get the last testpart of the test.
TestPart item = context.TestPart
.Include(tp => tp.Jobs) //possibly optional dependent on lazy/eager loading.
.OrderByDescending(tp=>tp.Id)
.First(tp => tp.TestId == 100);
//Check if this item fits the criteria
bool isValid =
item.Status == 1
&& item.Jobs.All(j => j.Type == "Recurring");
isValid
包含您的答案。
修改 - 仅为完整性
有一些方法可以将它合并到一个查询中,但这会使代码容易被误解。
bool isLastItemValid = context.TestPart
.Where(tp => tp.TestId == 100)
.OrderByDescending(tp => tp.Id)
.Take(1)
.Any(tp =>
tp.Status == 1
&& tp.Jobs.All(j => j.Type == "Recurring");
这会给你相同的结果。它依赖于“只有一个项目在列表上调用Any()
的”技巧“。
虽然技术上正确,但我觉得这个版本不必要地复杂,可读性差,而且更容易被开发人员误解。
答案 1 :(得分:2)
将.Take(1).Where()
替换为FirstOrDefault()
TestPart item = context.TestPart.OrderByDescending(tp => tp.Id)
.FirstOrDefault(tp => tp.TestId == 100 &&
tp.Status == 1 &&
tp.Jobs.All(j => j.Type == "Recurring");
int result = item.Id;
答案 2 :(得分:1)
我认为适当的做法是将其分解为步骤。我确实喜欢像下一个人那样的大型LINQ语句,但只有当它优雅地代表了所需的逻辑时。在这种情况下,您需要获取记录,检查其状态并返回其ID,那么为什么不在ROC中表达呢?
var lastPart = context.TestPart.OrderByDescending(tp=>tp.Id)
.First();
bool match = (lastPart.TestId == 100 &&
lastPart.Status == 1 &&
lastPart.Jobs.All( j => j.Type == "Recurring"));
if (match) return lastPart.Id;