【发布时间】:2013-11-01 20:47:14
【问题描述】:
我正在从另一个数据库导入数据。
我的过程是将远程数据库中的数据导入到名为remoteData 的List<DataModel> 中,并将本地数据库中的数据导入到名为localData 的List<DataModel> 中。
然后我使用 LINQ 创建一个不同的记录列表,以便我可以更新本地数据库以匹配从远程数据库中提取的数据。像这样:
var outdatedData = this.localData.Intersect(this.remoteData, new OutdatedDataComparer()).ToList();
然后我使用 LINQ 创建一个记录列表,这些记录在remoteData 中不再存在,但在localData 中确实存在,因此我将它们从本地数据库中删除。
像这样:
var oldData = this.localData.Except(this.remoteData, new MatchingDataComparer()).ToList();
然后我使用 LINQ 执行与上述相反的操作,将新数据添加到本地数据库。
像这样:
var newData = this.remoteData.Except(this.localData, new MatchingDataComparer()).ToList();
每个集合导入大约 7 万条记录,3 次 LINQ 操作中的每一个都需要 5 到 10 分钟才能完成。 我怎样才能加快速度?
这是集合使用的对象:
internal class DataModel
{
public string Key1{ get; set; }
public string Key2{ get; set; }
public string Value1{ get; set; }
public string Value2{ get; set; }
public byte? Value3{ get; set; }
}
用于检查过时记录的比较器:
class OutdatedDataComparer : IEqualityComparer<DataModel>
{
public bool Equals(DataModel x, DataModel y)
{
var e =
string.Equals(x.Key1, y.Key1) &&
string.Equals(x.Key2, y.Key2) && (
!string.Equals(x.Value1, y.Value1) ||
!string.Equals(x.Value2, y.Value2) ||
x.Value3 != y.Value3
);
return e;
}
public int GetHashCode(DataModel obj)
{
return 0;
}
}
用于查找新旧记录的比较器:
internal class MatchingDataComparer : IEqualityComparer<DataModel>
{
public bool Equals(DataModel x, DataModel y)
{
return string.Equals(x.Key1, y.Key1) && string.Equals(x.Key2, y.Key2);
}
public int GetHashCode(DataModel obj)
{
return 0;
}
}
【问题讨论】:
-
你应该真的实现哈希码。
-
哈希码用于在哈希表中定位对象,这可能是
Except和Intersect在内部用于查找匹配对象的方法。通过返回一个常数值,所有对象将具有相同的位置,并且对匹配的搜索降级为所有候选对象之间的线性搜索。您需要根据用于相等的属性正确实现GetHashCode。 -
正确。我添加了一个哈希码,操作需要一瞬间!谢谢。
标签: c# performance algorithm linq collections