我们的一些数据并不是最干净的。例如,如果一个人以两种不同的方式给出了他们的地址,他可能会在输出中出现两次:一次用" RD"再次使用" Road。"
有趣的是,有一半的数据出现在一个记录中,一半出现在另一个记录中。所以......
Johnny, Larsen Rd, Tuesday, 4 milk bottles
Johnny, Larsen Road, Tuesday, 3 milk bottles
事实上,约翰尼周二的消费是7瓶牛奶。我试图编写一个合并这两个对象的LINQ而不会太痛苦,但这是我到目前为止所有这些:
var records = report.GroupBy(r => r.Date)
.Select(n => new MilkBottleRecord() {
Name = report.First().Name,
Address = report.First().Address,
Date = report.First().Date,
Bottles = n.Sum(x => x.Bottles),
});
有什么建议吗?
我应该指出:A)这不是我们的数据,因此我们无法真正进行清理,B)我们通过CSV而不是SQL查询来获取它。
此外,上述查询中唯一相关的信息是日期,因为我已在先前的查询中分离出不同的帐户。由于那个很好,我没想到把它包括在这里是值得的。
答案 0 :(得分:3)
不是使用痛苦的写入查询,而是更好地浏览数据库并合并重复的记录?如果你这样做,你的查询会看起来更好。
答案 1 :(得分:1)
您可以尝试这样的事情:
IEqualityComparer<MilkBottleRecord> comparer = /* instantiate a comparer */
var records = report.GroupBy(x => x, comparer)
.Select(g => new MilkBottleRecord(g.Key) {
Bottles = g.Sum(x => x.Bottles))
});
基本思路是:外化你的比较逻辑,创建一个复制构造函数,允许你复制显着信息,然后用Sum覆盖Bottles字段。
答案 2 :(得分:0)
履行公司使用CASS软件来修复和规范地址。如果你正在做一些专业的事情,你可能会考虑到这一点。
否则,您可以执行以下操作:
string NormalizeAddress(string str)
{
// should probably be a bit more intelligent than this, but maybe not.
str = str.ToUpperInvariant();
str = str.Replace ("ROAD", "RD");
return str;
}
var records = report.GroupBy(r =>
Tuple.Create(r.Date, NormalizeAddress(r.Address)))
答案 3 :(得分:0)
如果您无法更改数据结构,那么
之类的内容如何var records = report.GroupBy(r => r.Date)
.Select(n => new MilkBottleRecord(report.First, n.Sum(x => x.Bottles)));
和构造函数
MilkBottleReport(MilkBottleReport original, int newBottles);
答案 4 :(得分:0)
作为您问题的答案 - 创建一个copy constructor,您的LINQ看起来更好 但正如archer884所说,LINQ可能会窒息;而且我补充说,做一大块数据而无法知道进度是不好的 - 按记录迭代记录 另外:正如zmbq所说 - 将数据清理移动到它自己的模块/ dll /汇编/机器/流程/业务。
答案 5 :(得分:0)
真正的答案是清理和规范化您的数据。决定是否在地址中使用拼写或缩写类型的道路(Road / Rd,Avenue / Av / Ave,Street / St,Drive / Dr,Lane / Ln),然后更改您的数据以符合您的标准已经选择并重复使用。
答案的另一部分是使用不可变标识符来区分记录。你最终可能会有两个名叫“约翰尼”的不同的人住在“拉森路”上。它甚至可能是拉森路一样的;约翰和绰号约翰尼很常见,很容易就会有两个约翰尼住在特定拉森路上的约翰尼。他们希望通过姓氏,地段或公寓号来区分,但如果您认为这些数据中的任何一个都是可疑的,那么您仍然会遇到问题。该解决方案是一个唯一的标识符,例如帐号,可以让您积极区分生活在拉森路上的两个不同的人Johnny,或相反地识别任何其他“唯一识别信息”的差异,否则会导致您误认为一个人两个人。
LINQ并不是万灵药,虽然您可能会使用LINQ提出一个通用的规范化查询,但我不想让您支持并维护它。还有其他工具可用于将真实数据清理成计算机可以匹配的内容。