c# - 将整数谓词与 LINQ 进行比较
问题描述
我有这个简单的查询,我需要在 EF Core 的 api 端识别特定 TicketBook 对象的开始和结束编号内的所有票证。
var ticketBook = await Context.TicketBooks.FirstOrDefaultAsync(x=>x.Id == query.TicketBookId);
if (ticketBook != null)
{
dbTickets = dbTickets.Where(x => ConvertTicketNumberToInt(x, ticketBook));
}
private bool ConvertTicketNumberToInt(Ticket t, TicketBook tb)
{
try
{
var numberOnly = new string(t.Number.Where(t => char.IsDigit(t)).ToArray());
var tNumber = Convert.ToInt64(numberOnly);
return tNumber >= tb.StartIntNumber && tNumber <= tb.EndIntNumber;
}
catch(OverflowException)
{
return false;
}
}
问题是 Ticket 类中的“数字”属性是 nvarchar(字符串),但我需要将它转换为整数,仅用于这个特定的查询,为此我编写了一个小方法来为我做这件事。但是正如您所看到的那样,它非常耗时且根本没有效率,所以我的 api 调用只是超时了。
我试图弄清楚如何在 LINQ 中做到这一点,而无需编写像这样的额外方法。诀窍是“数字”属性有时可以在其中包含一些字母,这会在将其转换为整数时引发异常,因此我需要在比较之前删除那些非数字字符,这就是为什么我必须为它编写这个专用方法的原因。
解决方案
如前所述,您面临存储nvarchar
而不是长时间存储的一些性能问题。
无论如何,您在代码中所做的事情并没有那么糟糕——您有相当简单的方法可以让您的 LINQ 代码保持干净整洁。但是由于您想要一个 LINQ 查询,请尝试以下操作(它可以做得更短,但我选择这种方式是为了便于阅读):
var ticketBook = await Context.TicketBooks.FirstOrDefaultAsync(x=>x.Id == query.TicketBookId);
if (ticketBook != null)
{
dbTickets = dbTickets
.Select(t => new { Ticket = t, Number = new string(t.Number.Where(n => char.IsDigit(n)).ToArray()) })
.Select(t =>
{
long ticketNumber = long.MinValue;
long.TryParse(t.Number), out ticketNumber);
return new { Ticket = t, Number = ticketNumber };
})
.Where(t => t.Ticket >= ticketBook.StartIntNumber && t.Ticket <= ticketBook.EndIntNumber)
.Select(t => t.Ticket);
}
它能做什么:
- 在第一次传递中,您的所有字母都被剥离并转换为仅包含数字的字符串,然后与此字符串一起返回具有
varchars
完整类的匿名类型Ticket
- 字符串被解析为很长 - 我滥用
long.MinValue
表示转换失败(因为你正在使用char.IsDigit(c)
我看到你不希望结果中有任何负值。你最好使用ulong
两倍的正范围并滥用 0 值) 再次返回一个匿名类型 - 这些匿名结构会根据您提供的条件进行过滤
- 最后,只返回原始
Ticket
结构
如果您担心初始结果的通过次数 - 我已经运行了几次性能测试,以确定Select
内部是否有许多带有短操作的 s 是否比使用复杂操作的一次通过要慢,我没有观察到任何显着差异。
推荐阅读
- python - Keras 模型的 YellowbrickTypeError:此估计器不是分类器;尝试使用回归或聚类分数可视化工具
- javascript - 每次触发上述元素动画时,如何保持 HTML/CSS 元素固定而不是抖动/调整?
- selenium-chromedriver - WebDriverException:消息:未知错误:Chrome 无法启动:崩溃。- RobotFramework- Pycharm
- kubernetes - 无法在 Openshift 中按名称解析服务
- r - 如何在r中的新列中对具有字符值的列进行分组
- java - 我无法在 requestparams 中设置一个条件来比较和获取实体类的输出
- spring - 如何在 Spring Controller 中在运行时检查子类类型
- python - 在数据框中识别第一次出现的字符串,直到出现另一个字符串
- python - 一种在 for 循环中为每个子图更新图形布局的方法 (Plotly)
- c++ - 满足某个概念的所有完整类型的元组