C# 如何使用LINQ从通用列表中获取下一个适当的值?
我有一门课:C# 如何使用LINQ从通用列表中获取下一个适当的值?,c#,linq,generics,lambda,generic-list,C#,Linq,Generics,Lambda,Generic List,我有一门课: public class CounselPoints { public int CounselNum { get; set; } public String CounselPoint { get; set; } public bool BR { get; set; } public bool ICRVBS { get; set; } } …以及该类的通用列表: List<CounselPoints> counselPoints = AY
public class CounselPoints
{
public int CounselNum { get; set; }
public String CounselPoint { get; set; }
public bool BR { get; set; }
public bool ICRVBS { get; set; }
}
…以及该类的通用列表:
List<CounselPoints> counselPoints = AYttFMConstsAndUtils.DeserializeCounselPointsFile();
我调用此方法来尝试获取该值,并像这样挥舞着:
public static int GetNextBibleReadingCounselPoint(int LastCounselPoint)
{
List<CounselPoints> counselPoints = AYttFMConstsAndUtils.DeserializeCounselPointsFile();
return counselPoints.FirstOrDefault(i => i.CounselNum).Where(j => j.BR).Where(k => k.CounselNum > LastCounselPoint);
}
我得到:
错误CS1061“CounselPoints”不包含“Where”的定义,并且找不到接受“CounselPoints”类型的第一个参数的扩展方法“Where”(是否缺少using指令或程序集引用?
…这也只会让我告诉编译器,“除了九个,伙计,都搞定了;把他们放在另一条巷子里。”
解开这个难题的关键是什么?使用查询时,首先需要使用筛选条件,然后才调用
FirstOrDefault
:
return counselPoints
.Where(j => j.BR)
.Where(k => k.CounselNum > LastCounselPoint)
.Select(i => i.CounselNum)
.FirstOrDefault();
有两种类型的LINQ查询运算符-<代码>其中是延迟运算符的示例,FirstOrDefault
是立即运算符
在您的代码中,您对无序列表使用了FirstOrDefault
,因此您立即过滤了初始列表
在我提供的示例代码中,我首先使用延迟运算符定义过滤器,然后才使用即时函数检索结果。使用查询时,首先需要使用过滤条件,然后才调用
FirstOrDefault
:
return counselPoints
.Where(j => j.BR)
.Where(k => k.CounselNum > LastCounselPoint)
.Select(i => i.CounselNum)
.FirstOrDefault();
有两种类型的LINQ查询运算符-<代码>其中是延迟运算符的示例,FirstOrDefault
是立即运算符
在您的代码中,您对无序列表使用了FirstOrDefault
,因此您立即过滤了初始列表
在我提供的示例代码中,我首先使用延迟运算符定义过滤器,然后才使用立即函数检索结果。试试这个
counselPoints
.Where(j => j.BR && j.CounselNum > LastCounselPoint)
.FirstOrDefault();
试试这个
counselPoints
.Where(j => j.BR && j.CounselNum > LastCounselPoint)
.FirstOrDefault();
我想dotnetom&Chris Moutray已经回答了这个问题,我只想补充一点:
下次使用LINQ语句时,请尝试将它们拆分为单独的语句。这样做,您将看到
FirstOrDefault()
在Where()之前没有任何意义,因为它将返回单个对象,并且您不能在单个对象上使用Where,对吗?:) 我想dotnetom&Chris Moutray已经回答了这个问题,我只想补充一点:
下次使用LINQ语句时,请尝试将它们拆分为单独的语句。这样做,您将看到FirstOrDefault()
在Where()之前没有任何意义,因为它将返回单个对象,并且您不能在单个对象上使用Where,对吗?:) 我在您的示例(以及其他Anwser)中看到您编写的第一个默认值是这样的:.FirstOrDefault(I=>I.CounselNum)
,但我认为您不需要这个
将第一个默认值视为过滤器,而不是选择
所以你需要这样写
return counselPoints
.Where(cp => cp.BR && cp.CounselNum > LastCounselPoint) // where clause
.Select(cp => cp.CounselNum) // select part
.FirstOrDefault(); // get top 1 only
return counselPoints
.OrderBy(cp => cp.CounselNum) // order by ascending
.Where( ... rest of code
*更新>已存在
正如@Jannik指出的,当没有匹配项时,上面的返回值是零而不是null
如果同时测试存在性很重要,那么你可以这样写
CounselPoint cp = counselPoints
.Where(cp => cp.BR && cp.CounselNum > LastCounselPoint) // where clause
.FirstOrDefault(); // get top 1 object of type CounselPoint
if (cp == null)
return null;
return cp.CounselNum;
请注意,方法的返回类型必须是可为null的int。请参阅下面添加的?
public static int? GetNextBibleReadingCounselPoint(int LastCounselPoint)
。。。然后我猜你的电话号码来检查结果
int? result = GetNextBibleReadingCounselPoint(lastCounselPoint);
if (result.HasValue) {
// something was returned
} else {
// nothing was returned
int num = result.Value;
}
*更新2>订单
想想你原来的SQL-我想知道你是否没有考虑订单
也许您应该在底部添加一个订单:
SELECT TOP 1 CounselNumber
FROM COUNSELPOINTSLU
WHERE BR IS TRUE
AND CounselNumber > @LastCounselPoint
ORDER BY CounselNumber; // ascending
在这种情况下,您可以在linq语句的where子句之前添加order by;像这样
return counselPoints
.Where(cp => cp.BR && cp.CounselNum > LastCounselPoint) // where clause
.Select(cp => cp.CounselNum) // select part
.FirstOrDefault(); // get top 1 only
return counselPoints
.OrderBy(cp => cp.CounselNum) // order by ascending
.Where( ... rest of code
我在您的示例(以及其他Anwser)中看到,您编写的第一个默认值是这样的:.FirstOrDefault(I=>I.CounselNum)
,但我认为您不需要这样
将第一个默认值视为过滤器,而不是选择
所以你需要这样写
return counselPoints
.Where(cp => cp.BR && cp.CounselNum > LastCounselPoint) // where clause
.Select(cp => cp.CounselNum) // select part
.FirstOrDefault(); // get top 1 only
return counselPoints
.OrderBy(cp => cp.CounselNum) // order by ascending
.Where( ... rest of code
*更新>已存在
正如@Jannik指出的,当没有匹配项时,上面的返回值是零而不是null
如果同时测试存在性很重要,那么你可以这样写
CounselPoint cp = counselPoints
.Where(cp => cp.BR && cp.CounselNum > LastCounselPoint) // where clause
.FirstOrDefault(); // get top 1 object of type CounselPoint
if (cp == null)
return null;
return cp.CounselNum;
请注意,方法的返回类型必须是可为null的int。请参阅下面添加的?
public static int? GetNextBibleReadingCounselPoint(int LastCounselPoint)
。。。然后我猜你的电话号码来检查结果
int? result = GetNextBibleReadingCounselPoint(lastCounselPoint);
if (result.HasValue) {
// something was returned
} else {
// nothing was returned
int num = result.Value;
}
*更新2>订单
想想你原来的SQL-我想知道你是否没有考虑订单
也许您应该在底部添加一个订单:
SELECT TOP 1 CounselNumber
FROM COUNSELPOINTSLU
WHERE BR IS TRUE
AND CounselNumber > @LastCounselPoint
ORDER BY CounselNumber; // ascending
在这种情况下,您可以在linq语句的where子句之前添加order by;像这样
return counselPoints
.Where(cp => cp.BR && cp.CounselNum > LastCounselPoint) // where clause
.Select(cp => cp.CounselNum) // select part
.FirstOrDefault(); // get top 1 only
return counselPoints
.OrderBy(cp => cp.CounselNum) // order by ascending
.Where( ... rest of code
我得到了前两个compile err msg,还有这个(CS0029和CS1662)@B.ClayShannon你完全正确,我必须更仔细地阅读错误消息。更新了答案。我得到了前两个compile err msg,还有这个(CS0029和CS1662)@B.ClayShannon你完全正确,我必须更仔细地阅读错误消息。更新了答案。我得到了:严重性代码描述项目文件行抑制状态错误CS0029无法将类型“AYttFMScheduler.CONSOLLPOINTS”隐式转换为“int”,我得到了:严重性代码描述项目文件行抑制状态错误CS0029无法将类型“AYttFMScheduler.CONSOLLPOINTS”隐式转换为'int'另一侧注意:如果在中没有适当的条目,则返回0list@Jannik更新-也考虑顺序,因为这似乎是下一个逻辑步骤另一方面注意:如果在中没有适当的条目,则返回0list@Jannik更新-还考虑订单,因为这似乎是下一个逻辑步骤请参阅我的答案…请参阅我的答案中添加的改进。。。