在LINQ to Objects / SQL / Entity中的单个列上使用GroupBy从集合中获取不同的对象

时间:2013-05-22 11:49:51

标签: c# linq linq-to-sql linq-to-entities

我有一个数据库表Country,其示例数据如下:

CountryId        CountryName         Year
1                 UK                 2001
2                 UK                 2003
3                 UK                 2004
4                 USA                2001
5                 USA                2005

我的DataAccessLevel上有一个GetAllCountries()方法:

public static IEnumerable<Country> GetAllCountries()
    {
        List<Country> countries;
        using (var context = new ReportEntities())
        {
            countries= (from c in context.Countries 
                       select c).ToList();
        }
           return countries;
    }

那应该返回一个Country对象列表,然后我可以使用它来绑定DropdDownList来显示数据。当我绑定时,我使用它来从对象中选择要显示的特定属性。所以我需要List,以便以后我可以在不同的数据加载方法中使用它。例如,在LoadCountriesToDdlList()中:

{
       var countries= _transactionService.GetAllCountries();
        var distinctcountries = countries.GroupBy(c=> c.CountryName); 
        _UIDDListCountries.DataSource = distinctcountries ;
}

列表的预期结果: 的国家或地区名称
      英国
      美国

我尝试了很多不同的方法来编辑查询,但每次都失败了。有任何想法吗?

尝试:GrouppBy,OrderedBy,Distinct(),选择新对象,但没有运气。问题似乎是我试图返回一个对象列表。

4 个答案:

答案 0 :(得分:0)

听起来你想要这个

countries= (from c in context.Countries 
            select c.CountryName).Distinct()

答案 1 :(得分:0)

GroupBy()应该会为您提供您所追求的内容:

var grouped = context.Countries.GroupBy(c => c.CountryName);

    foreach (var country in grouped)
    {
        var distinctCountryName = country.Key;  //Access field used to group
        var firstMatchingCountry = country.First();
        var matchingCountriesInAList = country.ToList();
    }

答案 2 :(得分:0)

如果国家名称很重要,您可以使用以下内容......如countryId和year中那样。

//Note, you'll probably want to change this function name because it's
//not actually getting all countries anymore
public static IEnumerable<Country> GetAllCountries()
{
    using (var context = new ReportEntities())
    {
        //Note, this LINQ query can also return an IQueryable.  This is useful
        //if you're querying a database because you'll be doing more logic in SQL
        //and transferring less data from your database to memory on your C# machine
        IEnumerable<Country> countries = 
                 from c in context.Countries
                 group c by c.CountryName into countriesGroupedByName
                 select countriesGroupedByName.First();
        return countries;
    }
}

如果您关心countryIdcountryName,请执行以下操作。

IEnumerable<Country> countries = 
                    from c in context.Countries
                    group c by c.CountryName into countriesGroupedByName
                    select countriesGroupedByName.OrderBy(c => c.CountryId).First();

答案 3 :(得分:0)

如果您只想让下拉列表中的上述国家/地区名称不同,您可以尝试以下方法:

{
       var countries= _transactionService.GetAllCountries();
        var distinctcountries = countries.GroupBy(c=> c.CountryName); 
        _UIDDListCountries.DataSource = distinctcountries.Select(g => g.First());
}

上面的代码首先根据CountryName对所有国家/地区对象进行分组,然后我们只将每个分组结果的第一个对象分配给下拉数据源。

如果要自定义文本字段值,可以创建匿名类型并使用它。代码如下:

{
       var countries= _transactionService.GetAllCountries();
       var distinctcountries = countries.GroupBy(c=> c.CountryName); 
       _UIDDListCountries.DataSource = distinctcountries.Select(g => new { CountryID = g.First().CountryID, CountryName = g.First().CountryName ,Text = String.Concat(g.First().CountryName, "--", g.First().Year) }) ;
       _UIDDListCountries.DataTextField = "Text";
       _UIDDListCountries.DataValueField = "CountryName";
}

注意:当您只关心在下拉列表中显示CountryNames的不同值而不考虑CountryID和Year时,这是有效的