我想将一组修改过的记录与从数据库中提取的记录列表进行比较,并从数据库中删除那些在传入数组中不存在的记录.修改后的数组来自维护数据库的客户端应用程序,此代码在WCF服务应用程序中运行,因此如果客户端从数组中删除记录,则应从数据库中删除该记录.以下是示例代码段:
public void UpdateRecords(Record[] recs)
{
// look for deleted records
foreach (Record rec in UnitOfWork.Records.ToList())
{
var copy = rec;
if (!recs.Contains(rec)) // use this one?
if (0 == recs.Count(p => p.Id == copy.Id)) // or this one?
{
// if not in the new collection, remove from database
Record deleted = UnitOfWork.Records.Single(p => p.Id == copy.Id);
UnitOfWork.Remove(deleted);
}
}
// rest of method code deleted
}
Run Code Online (Sandbox Code Playgroud)
我的问题:使用Count方法比Contains方法有速度优势(或其他优势)吗?Id属性保证是唯一的并且用于标识该特定记录,因此您不需要进行按位比较,因为我假设Contains可能会这样做.
任何人?谢谢,戴夫
Bro*_*ass 35
这会更快:
if (!recs.Any(p => p.Id == copy.Id))
Run Code Online (Sandbox Code Playgroud)
这有相同的优点,使用Count()-但它也停止它找到第一个匹配后不像Count()
Joã*_*elo 13
您甚至不应该考虑,Count因为您只检查是否存在记录.你应该使用Any.
使用Countforce迭代整个枚举以获得正确的计数,Any一旦找到第一个元素就停止枚举.
至于使用Contains你需要考虑的是,对于指定的类型引用,是否等同于Id您正在执行的比较.默认情况下不是这样.
假设Record实现两者GetHashCode并且Equals正确,我将完全使用不同的方法:
// I'm assuming it's appropriate to pull down all the records from the database
// to start with, as you're already doing it.
foreach (Record recordToDelete in UnitOfWork.Records.ToList().Except(recs))
{
UnitOfWork.Remove(recordToDelete);
}
Run Code Online (Sandbox Code Playgroud)
基本上没有必要具有N*M查找时间 - 上面的代码将最终recs根据其哈希代码构建一组记录,并且比原始代码更有效地查找非匹配.
如果你真的有更多事要做,你可以使用:
HashSet<Record> recordSet = new HashSet<Record>(recs);
foreach (Record recordFromDb in UnitOfWork.Records.ToList())
{
if (!recordSet.Contains(recordFromDb))
{
UnitOfWork.Remove(recordFromDb);
}
else
{
// Do other stuff
}
}
Run Code Online (Sandbox Code Playgroud)
(我不太清楚为什么你的原始代码是Single在你已经把它作为rec...的时候从数据库中重新获取记录的.)
Contains()将用于Equals()对付你的对象.如果您没有覆盖此方法,甚至可能Contains()返回不正确的结果.如果你重写它使用对象的Id确定身份,那么在这种情况下Count(),并Contains()几乎在做同样的事情.除了Contains()一旦碰到比赛就会短路,在那里Count()继续计数.Any()可能是比他们两个更好的选择.
您是否确定这是您应用中的瓶颈?感觉就像我过早优化一样.这是万恶之源,你知道:)