重构 linq 语句
我有一个在 LINQPad 中使用的 linq 表达式,我想重构该表达式,以用单个测试替换 idx == -1 的所有测试。此输入数据是对用于缓存 Active Directory 信息的数据库进行自由文本搜索的结果。搜索会返回匹配数据库行中的显示名称和关联摘要数据的列表。我想从该列表中提取显示名称和匹配的 Active Directory 条目。有时,匹配仅发生在显示名称上,因此可能没有进一步的上下文。在下面的示例中,字符串“Sausage”旨在作为返回 matches 数组中两项的搜索词。显然,实际搜索的情况并非如此,因为第二个数组项中没有匹配“Sausage”。
var matches = new []
{
new { displayName = "Sausage Roll", summary = "|Title: Network Coordinator|Location: Best Avoided|Department: Coordination|Email: [email protected]|" },
new { displayName = "Hamburger Pattie", summary = "|Title: Network Development Engineer|Location: |Department: Planning|Email: [email protected]|" },
};
var context = (from match in matches
let summary = match.summary
let idx = summary.IndexOf("Sausage")
let start = idx == -1 ? 0 : summary.LastIndexOf('|', idx) + 1
let stop = idx == -1 ? 0 : summary.IndexOf('|', idx)
let ctx = idx == -1 ? "" : string.Format("...{0}...", summary.Substring(start, stop - start))
select new { displayName = match.displayName, summary = ctx, })
.Dump();
我正在尝试创建一个名称列表和搜索结果的一些上下文(如果存在)。下面的输出表示 Dump() 显示的内容,并且是正确的结果:
displayName summary
---------------- ------------------------------------------
Sausage Roll ...Email: [email protected]...
Hamburger Pattie
编辑:正则表达式版本如下,绝对更整洁:
Regex reg = new Regex(@"\|((?:[^|]*)Sausage[^|]*)\|");
var context = (from match in matches
let m = reg.Match(match.summary)
let ctx = m.Success ? string.Format("...{0}...", m.Groups[1].Value) : ""
select new { displayName = match.displayName, context = ctx, })
.Dump();
I have a linq expression that I've been playing with in LINQPad and I would like to refactor the expression to replace all the tests for idx == -1
with a single test. The input data for this is the result of a free text search on a database used for caching Active Directory info. The search returns a list of display names and associated summary data from the matching database rows. I want to extract from that list the display name and the matching Active Directory entry. Sometimes the match will only occur on the display name so there may be no further context. In the example below, the string "Sausage" is intended to be the search term that returned the two items in the matches array. Clearly this wouldn't be the case for a real search because there is no match for Sausage in the second array item.
var matches = new []
{
new { displayName = "Sausage Roll", summary = "|Title: Network Coordinator|Location: Best Avoided|Department: Coordination|Email: [email protected]|" },
new { displayName = "Hamburger Pattie", summary = "|Title: Network Development Engineer|Location: |Department: Planning|Email: [email protected]|" },
};
var context = (from match in matches
let summary = match.summary
let idx = summary.IndexOf("Sausage")
let start = idx == -1 ? 0 : summary.LastIndexOf('|', idx) + 1
let stop = idx == -1 ? 0 : summary.IndexOf('|', idx)
let ctx = idx == -1 ? "" : string.Format("...{0}...", summary.Substring(start, stop - start))
select new { displayName = match.displayName, summary = ctx, })
.Dump();
I'm trying to create a list of names and some context for the search results if any exists. The output below is indicative of what Dump() displays and is the correct result:
displayName summary
---------------- ------------------------------------------
Sausage Roll ...Email: [email protected]...
Hamburger Pattie
Edit: Regex version is below, definitely tidier:
Regex reg = new Regex(@"\|((?:[^|]*)Sausage[^|]*)\|");
var context = (from match in matches
let m = reg.Match(match.summary)
let ctx = m.Success ? string.Format("...{0}...", m.Groups[1].Value) : ""
select new { displayName = match.displayName, context = ctx, })
.Dump();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
(我知道这并不能回答你的具体问题),但无论如何,这是我的贡献:
你还没有真正描述你的数据是如何进来的。正如@Joe所建议的,你可以使用正则表达式或像我一样分割字段以下。
不管怎样,我建议重构你的代码以允许单元测试。
否则,如果您的数据无效/损坏,您将在 linq 查询中收到运行时错误。
(I know this doesn't answer your specific question), but here's my contribution anyway:
You haven't really described how your data comes in. As @Joe suggested, you could use a regex or split the fields as I've done below.
Either way I would suggested refactoring your code to allow unit testing.
Otherwise if your data is invalid / corrupt whatever, you will get a runtime error in your linq query.
或者类似的东西:
我还没有测试过这个,可能甚至没有正确的语法,但只是为了让您了解如何使用正则表达式来做到这一点。
更新
好的,我已经看到你的答案,很高兴你发布它,因为我认为我没有解释清楚。
我希望你的答案最后看起来像这样(现在使用 LINQPad 进行测试,现在我明白你使用 LINQPad 的意思,因为它实际上运行 C# 程序而不仅仅是 linq 命令,太棒了!)无论如何,这就是它应该做的看起来像:
就是这样,整个事情,完全去掉 linq!
我希望这能解决问题,你根本不需要 linq。
Or something like this:
I haven't tested this, probably not even correct syntax but just to give you an idea of how you could do it with regex.
Update
Ok, i've seen your answer and it's good that you posted it because I think i didn't explain it clearly.
I expected your answer to look something like this at the end (tested using LINQPad now, and now i understand what you mean by using LINQPad because it actually does run a C# program not just linq commands, awesome!) Anyway this is what it should look like:
That's it, the whole thing, take linq out of it, completely!
I hope this clears it up, you do not need linq at all.
像这样?
like this?