简体   繁体   English

List.Except方法返回错误的结果

[英]List.Except method returns the wrong results

Im trying to compare 2 Lists of the type Results, and it constantly just returns the entire list of results, it doesnt seem to filter anything out. 我试图比较结果类型为2的列表,并且它不断地只返回结果的整个列表,它似乎没有过滤掉任何东西。

This is the code : 这是代码:

  List<Results> Veranderingen = resultaten2.Except(resultaten).ToList();

        foreach(Results x in Veranderingen)
        {
            MessageBox.Show("Nieuwe Data gevonden: " + x.titel + "Van de website" + x.url + "");
        }

The code where the lists gets filled is this ( Less important ) : 列表被填充的代码是这样(不太重要):

 private void Lijst2invullen()
    {

        OleDbConnection connection = new OleDbConnection();
        connection.ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\martijn\Dropbox\Proftaak Periode 2 Identity\Database11.accdb;
        Persist Security Info=False;";
        connection.Open();

        OleDbCommand cmd2 = new OleDbCommand();
        cmd2.Connection = connection;
        cmd2.CommandText = "SELECT ZoekcriteriaID from Zoekcriteria WHERE ZoekCriteria = '" + Convert.ToString(cbzoektermselecteren.Text) + "';";
        OleDbDataReader reader2 = cmd2.ExecuteReader();

        if (reader2.Read())
        {
            refreshid2 = Convert.ToInt32(reader2["ZoekcriteriaID"]);
        }




        OleDbCommand command5 = new OleDbCommand();
        command5.Connection = connection;
        command5.CommandText = "SELECT Titel, Webadress from Resultaat WHERE ZoekcriteriaID = " + refreshid2 + ";";
        OleDbDataReader reader3 = command5.ExecuteReader();

        while (reader3.Read())
        {
            Results result = new Results();
            result.url = Convert.ToString(reader3["Webadress"]);
            result.titel = Convert.ToString(reader3["Titel"]);

            resultaten2.Add(result);
        }
        reader3.Close();
        label1.Text = "Ziet er goed uit!";
    }

    private void Lijst1invullen()
    {
        OleDbConnection connection = new OleDbConnection();
        connection.ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\martijn\Dropbox\Proftaak Periode 2 Identity\Database11.accdb;
        Persist Security Info=False;";
        connection.Open();


        OleDbCommand cmd1 = new OleDbCommand();
        cmd1.Connection = connection;
        cmd1.CommandText = "SELECT ZoekcriteriaID from Zoekcriteria WHERE ZoekCriteria = '" + Convert.ToString(cbzoektermselecteren.Text) + "';";
        OleDbDataReader reader1 = cmd1.ExecuteReader();

        if (reader1.Read())
        {
            refreshid = Convert.ToInt32(reader1["ZoekcriteriaID"]);
        }


        OleDbCommand command = new OleDbCommand();
        command.Connection = connection;
        command.CommandText = "SELECT Titel, Webadress from Resultaat WHERE ZoekcriteriaID = " + refreshid + ";";
        OleDbDataReader reader = command.ExecuteReader();



        while (reader.Read())
        {
            Results result = new Results();
            result.url = Convert.ToString(reader["Webadress"]);
            result.titel = Convert.ToString(reader["Titel"]);

            resultaten.Add(result);
        }
        reader.Close();
        reader1.Close();

        OleDbCommand command2 = new OleDbCommand();
        command2.Connection = connection;
        command2.CommandText = "DELETE * FROM Resultaat WHERE ZoekcriteriaID = " + refreshid + ";";
        command2.ExecuteNonQuery();

        OleDbCommand command3 = new OleDbCommand();
        command3.Connection = connection;
        command3.CommandText = "DELETE * FROM Zoekcriteria WHERE ZoekCriteriaID = " + refreshid + ";";
        command3.ExecuteNonQuery();

        search.zoekterm = cbzoektermselecteren.Text;
        search.InsertZoekcriteria();
        search.searchding();

    }

I think I'm doing something wrong in the syntax of the Except method could anyone help me out? 我认为我在Except方法的语法中做错了任何人可以帮助我吗?

There are two ways to compare (for equality) two Results objects (and all reference type objects in general): 有两种方法可以比较(相等)两个Results对象(以及一般所有引用类型的对象):

  • The first way is to compare the values of the properties of the two Results objects. 第一种方法是比较两个Results对象的属性值。

  • The second way is to compare the references themselves. 第二种方法是比较引用本身。 And by that I mean that two Results objects are equal if they are actually a single object but you have two references to it. 我的意思是,如果两个Results对象实际上是一个对象,但它们有两个引用,则它们相等。 For example, you can create a single Results object and put it in two lists. 例如,您可以创建一个Results对象并将其放在两个列表中。

The objects in the two lists are clearly different objects, so I am guessing that you want to use the first way of comparison. 两个列表中的对象显然是不同的对象,因此我猜您想使用第一种比较方法。

By default, equality check of reference type objects in C# is of the second type. 默认情况下,C#中引用类型对象的相等性检查属于第二种类型。 However, you can override this behavior if you want. 但是,如果需要,您可以覆盖此行为。

One way of overriding this behavior is to override the Equals and GetHashCode methods in the class. 覆盖此行为的一种方法是覆盖类中的EqualsGetHashCode方法。 Here is an example: 这是一个例子:

public class Results
{
    public string url { get; set; }
    public string title { get; set; }

    public override bool Equals(object obj)
    {
        Results other = obj as Results;

        if (other == null)
            return false;

        return other.url == this.url && other.title == this.title;
    }

    public override int GetHashCode()
    {
        return new {url, title}.GetHashCode();
    }
}

This way, we are telling the system how it should test equality for objects of this type. 这样,我们告诉系统它应该如何测试此类型对象的相等性。

I'm sure Yacoub's answer would work and is probably the preferred solution in most cases, but in case you can't modify the Results class, here is another way to do it. 我确信Yacoub的答案会起作用,并且在大多数情况下可能是首选的解决方案,但是如果您无法修改Results类,这是另一种方法。 Define an implementation of IEqualityComparer for Results, and then pass it as the second argument of the Except method. 为结果定义IEqualityComparer的实现,然后将其作为Except方法的第二个参数传递。 EDIT: 编辑:

class Results {
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

class ResultsEqualityComparer : IEqualityComparer<Results> {

    public bool Equals(Results res1, Results res2) {
        return (res1.FirstName == res2.FirstName && res1.LastName == res2.LastName);
    }

    public int GetHashCode(Results res) {
        return new { res.FirstName, res.LastName }.GetHashCode();
    }

}

// and here's the example of code passing the ResultsComparer to Except: //这是将ResultsComparer传递给Except的代码示例:

        var resultaten = new List<Results>() {
        new Results() {FirstName="Bob", LastName="Smith"},
        new Results() {FirstName="Ted", LastName="Wilson"},
        new Results() {FirstName="Alice", LastName="Wilson"},
        new Results() {FirstName="Carol", LastName="Smith"}
        };

        var resultaten2 = new List<Results>() {
        new Results() {FirstName="William", LastName="Smith"},
        new Results() {FirstName="Ted", LastName="Wilson"},
        new Results() {FirstName="Gerhardt", LastName="Wilson"},
        new Results() {FirstName="Carol", LastName="Smith"}
        };

        var comparer = new ResultsEqualityComparer();

        List<Results> Veranderingen = resultaten2.Except(resultaten, comparer).ToList();

        foreach (var x in Veranderingen) {
            Console.WriteLine(x.FirstName + " " + x.LastName);
        }

// prints out: William Smith Gerhardt Wilson //打印:William Smith Gerhardt Wilson

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM