C# Linq 不在数据表上的选择中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1164770/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 09:45:23  来源:igfitidea点击:

Linq not in select on datatable

c#linqdatatable

提问by nLL

Hi i've got 2 data tables (bannedlist,countrylist), both contains list of country names and cods in columns cc and country. I am trying to do a query where i can select countries from countrylist table that are not in bannedlist table in order to create a 3rd table.

嗨,我有 2 个数据表(bannedlist、countrylist),它们都包含在 cc 和 country 列中的国家名称和鳕鱼列表。我试图做一个查询,我可以从countrylist 表中选择不在bannedlist 表中的国家,以创建第三个表。

Any ideas?

有任何想法吗?

I haven't got too far with this.

我还没有走得太远。

        var ccList = ds.Tables[2].AsEnumerable(); 
        var bannedCCList = ds.Tables[1].AsEnumerable();
        var query = from r in ccList....

..

..

after trying

尝试后

var bannedCCList = ds.Tables[1].AsEnumerable();
    var query = from r in ccList where !bannedCCList.Any(b => b["cc"] == r["cc"])select r;

i still get same country list. banned ones haven't been removed. here is more detail in order to explain more. not sure what i am doing wrong

我仍然得到相同的国家/地区列表。被禁止的没有被删除。为了解释更多,这里有更多细节。不知道我做错了什么

 protected void BindCountryBan(string subd)
{
    DataSet ds = new DataSet();
    ds = new DB().CountryBan_GetSiteSettings();

        BannedCountryListBox.DataSource = ds.Tables[1];
        BannedCountryListBox.DataValueField = "cc";
        BannedCountryListBox.DataTextField = "country";
        BannedCountryListBox.DataBind();

//bind country list
    var ccList = ds.Tables[2].AsEnumerable(); 
    var bannedCCList = ds.Tables[1].AsEnumerable();
    var query = from r in ccList where !bannedCCList.Any(b => b["cc"] == r["cc"])select r;
    //var query = ccList.Except(bannedCCList); 




    //CountryListBox.DataSource = ds.Tables[2];
    DataTable boundTable = query.CopyToDataTable<DataRow>();
    CountryListBox.DataSource = boundTable;
    CountryListBox.DataValueField = "cc";
    CountryListBox.DataTextField = "country";
    CountryListBox.DataBind();
}

采纳答案by dahlbyk

Except would work if you use it on sequences of the countries:

如果您在国家/地区的序列上使用它,则除外:

using System.Linq;
...

    var ccList = from c in ds.Tables[2].AsEnumerable()
                 select c.Field<string>("Country"); 
    var bannedCCList = from c in ds.Tables[1].AsEnumerable()
                       select c.Field<string>("Country");
    var exceptBanned = ccList.Except(bannedCCList);

If you need the full rows where the countries aren't banned, you could try a left outer join:

如果您需要未禁止国家/地区的完整行,您可以尝试使用左外连接:

    var ccList = ds.Tables[2].AsEnumerable();
    var bannedCCList = ds.Tables[1].AsEnumerable();
    var exceptBanned = from c in ccList
                       join b in bannedCCList
                         on c.Field<string>("Country") equals b.Field<string>("Country") into j
                       from x in j.DefaultIfEmpty()
                       where x == null
                       select c;

回答by Meta-Knight

Try this:

尝试这个:

var query = ccList.Except(bannedCCList);

回答by Sébastien Ros - MSFT

You can use the Except() LINQ extension method like this:

您可以像这样使用 except() LINQ 扩展方法:

var result = full.Except(banned);

However this will work fine with the default comparer of the contained type. Thus if you want to use a specific column like in your example, you might need another approach like:

但是,这对于包含类型的默认比较器可以正常工作。因此,如果您想使用示例中的特定列,则可能需要另一种方法,例如:

from r in ccList
where !bannedCCList.Any(b => b["cc"] == r["cc"])
select r;

Using Except() implies the references are the same in both collections, which I think is not the case with Tables, or correct me if I'm wrong.

使用 Except() 意味着两个集合中的引用是相同的,我认为 Tables 不是这种情况,或者如果我错了,请纠正我。