0

在过去的十年里,我被卷入了一个被黑客攻击的项目之中。只是为了让大家知道:我已经建议并询问我们是否可以在继续开发之前重构数据库并审查系统的架构设计,但是多个较小的项目可交付成果比修复当前系统中的缺陷“更重要” .

话虽如此,如果存在完全匹配,检查代码的最佳方法是什么?

假设此表中有 75 列,超过 200 万行。

我知道我可以这样做:

var foo = bar.GetNewDocument();
dbContext.documents.Count(p => p.firstCol == foo.firstCol
                            && p.secondCol == foo.secondCol
                            && etc, etc);

这显然不是最好的解决方案......有没有更好的方法将代码中的这个新条目与其余条目进行比较以检查匹配?

4

2 回答 2

0

如果要进行sql查询,则需要构建表达式。例如:

    public static Expression<Func<T, bool>> GetEqualsExpression<T>(T obj)
    {
        var type = typeof (T);

        var x = Expression.Parameter(type, "x");

        BinaryExpression body = null;
        foreach (var propertyInfo in type.GetProperties())
        {
            var left = Expression.Property(x, propertyInfo);
            var right = Expression.Constant(propertyInfo.GetValue(obj, null));
            var equalsExpression = Expression.Equal(left, right);

            body = body == null ? equalsExpression : Expression.AndAlso(body, equalsExpression);
        }

        return Expression.Lambda<Func<T, bool>>(body, x);
    }

用法

        var foo = bar.GetNewDocument();
        var expression = GetEqualsExpression(foo);
        dbContext.documents.Count(expression);
于 2013-04-16T20:16:06.893 回答
0

使用HashSet<int>,在文档类中编写自定义散列方法

HashSet<int> hashes...;
dbContext.documents.ToList().ForEach(d=>{
  if (hashes.Contains(d.GetHash()))
    Console.WriteLine("Found one: "+d); // do further comparison here to ensure it's not hash collision
  else
    hashes.Add(d.GetHash());
});

请注意,如果 dbContext.documents 有太多您应该使用的条目,foreach而不是.ToList因为 ToList 会立即将它们全部拉下。

如果您不使用.ToList()并尝试直接使用它,哈希方法也将无法访问,例如dbContext.documents.Any(d=>d.GetHash()...)- 这将不起作用,因为它无法翻译成 SQL

如果经常执行此操作,您可以(!)添加另一个保存哈希的列(或添加一个保存它的表),这样重复检查的开销将非常小 - SQLServer 可以检查索引中的 200 万行columnt 非常非常快。

于 2013-04-16T19:10:30.710 回答