如何在保存到数据库之前维护唯一列表? - C#

时间:2010-11-16 00:21:10

标签: c# .net linq list collections

简化方案:

  • 我有List<Foo>
  • Foo有两个属性描述字符串), IsFoo bool

E.g:

var foos = new List<Foo>();

用户可以通过文本框“添加新的Foo”,然后在表单提交上执行此操作:

foos.Add(new Foo { Description = txtOne.Text, IsFoo = true });
foos.SaveToDb();

但是,有多个文本框,例如,如果他们在文本框中键入“FooBar”,则在文本框2中键入“FooBar”,我不希望显示错误< / strong>,但我根本不想将它们添加到集合中。 (不要担心背后的原因,这是一个简化的场景)。

我不需要向UI显示任何内容,只是在他们提交表单时,在持久保存到数据库之前我需要删除任何重复项(或者防止它们首先被添加到列表中)。 / p>

最简单/最好的方法是什么?字典也许?

我正在使用C#4,LINQ,.NET 4。

3 个答案:

答案 0 :(得分:3)

您可以使用HashSet<Foo>

HashSets是独特的无序集合 添加已存在的元素将无声地执行任何操作。 (并返回false

请注意,必须覆盖Equals类上的GetHashCodeFoo才能按值进行比较。

另请注意,hashsets本质上是无序的;如果您关心插入订单,则无法使用它。


或者,您可以使用LINQ检查您的列表是否有重复:

if (!foos.Any(f => f.Description == txtOne.Text))
    foos.Add(new Foo { Description = txtOne.Text, IsFoo = true });

答案 1 :(得分:2)

要扩展SLaks的答案,你可以这样做:

public class FooComparer : IEqualityComparer<Foo> {
    public static readonly FooComparer Instance = new FooComparer();

    private FooComparer() { }

    public bool Equals(Foo a, Foo b) {
        if (a == null)
            return b == null;

        if (b == null)
            return false;

        // For case-sensitivity:
        return a.Description == b.Description;

        // For case-insensitivity:
        return String.Equals(a.Description, b.Description, StringComparison.OrdinalIgnoreCase);
    }

    public int GetHashCode(Foo obj) {
        // For case-sensitivity:
        return obj.Description.GetHashCode();

        // For case-insensitivity:
        return StringComparer.OrdinalIgnoreCase.GetHashCode(obj.Description);
    }
}

然后将您的商品存储在HashSet<Foo>中,如下所示:

var hashSet = new HashSet<Foo>(FooComparer.Instance);
hashSet.Add(new Foo() { ... });

使用此代码,如果第二个Foo对象被添加到哈希集并且具有与哈希集中已存在的描述相同的描述,则将不会添加新对象。

答案 2 :(得分:0)

你能在linq中使用Distinct吗?

这是VB(并不准确,因为我没有在这台机器上安装VS),但有些内容如下:

Dim ie as IEnumerable(of Foo)= from obj As Foo In Foo's Select obj Distinct

然后实现IEqualityComparer? - 看起来像@cdhowie刚回答....