English 中文(简体)
LINQ GroupBy,将一对一名单改为一对一名单
原标题:LINQ GroupBy, convert a one-to-one list to a one-to-many

可以通过100万种方式做到这一点。

Problem. I have a list of servers which belongs to a country.

各国有许多服务器,因此其导航有两种方式(我认为其名称是)

Now I have a list of servers with there country set and want to group by country so I can get the opposite list.

List of countries with all there servers attached to the ICollection of the Country ( Servers )

var groupBy = list.GroupBy(x => x.Country, x => x, (c, s) => new {c, s});
foreach (var country in groupBy)
{
}

This will almost give me the result I want, but now I have 2 anon types. C which is country and S which is the list of servers.

How can I attach the list of servers to the country object s Collection.

班级类似......简化。

public class Server
{
    public short SID { get; set; }
    public Country Country { get; set; }
}

public class Country
{
    public byte CID { get; set; }
    public ICollection<Server> Servers { get; set; }
}

我猜测,我们可以建立一个有信息的新国家,然后把服务器名单放在建筑商......但我认为这种超技能。

......这种奇迹很简单,但我在这里失去了。

Update

我需要选择所有满足某种条件的服务器。 因此,我有一个国家服务器清单。 现在我刚刚需要改变名单。 能否以其他方式做到这一点?

I m using the Repository Pattern with EF 4 Code First. IRepository I only have the following methods available with a option to eager load a property: Single, SingleOrDefault, Find and FindAll

没有 la的负荷,他们都返回ICollection或一个T。

最佳回答

它像你真的想要建立从国家到服务器的眼光:

var lookup = servers.ToLookup(server => server.Country);

If that s not what you re looking for, please let me know how it doesn t do what you want :)

诚然,没有保证每个<代码>的国家都将在原始清单中拥有所有服务器,而这种区别确实是问题。

If your Server already has the Country set, can you not assume that the data is already consistent? If not, shouldn t your Server really have a CID instead of a Country reference? Having a property which will sometimes be consistent with "this" object and sometimes not (i.e. whether server.Country.Contains(server) is guaranteed to return true or not) is ugly IMO.

EDIT:Okae, 一种可能的nic子替代物是:

var query = servers.GroupBy(server => server.Country.CID);
                   .Select(g => new Country { CID = g.Key,
                                              Servers = g.ToList() });

This is almost the same as fermaref s approach, but I m explicitly using Country.CID to avoid two servers with equivalent countries not ending up in the same bucket due to potentially odd equality rules.

问题回答

现在,我有一份列有每个国家的服务器清单,希望按国家分类,这样我就可以确定相反的清单。

Linq is for querying and it has a functional mindset where you generate new instances instead of modifying existing instances.

如果你想改变这种情况,则先令:

List<Server> servers = GetServers();

foreach(Server server in servers)
{
  Country c = server.Country;
  c.Servers.Add(server);
}

如果你必须使用林克:

List<Server> servers = GetServers();

foreach(IGrouping<Country, Server> g in servers.GroupBy(s => s.Country))
{
  Country c = g.Key;
  c.Servers = g.ToList();
}

现在我刚刚需要改变名单。

ILookup<Country, Server> lookup = servers.ToLookup(s => s.Country);
List<Country> countries = lookup.Select(g => g.Key).ToList();
foreach(Country c in countries)
{
  c.Servers = lookup[c].ToList();
}
return countries;

如果您能保证每个<代码>的国家的物体已经包含所有服务器,则您可创建新的<代码>。 国家目标:

var groupBy = list.GroupBy(
                    x => x.Country, 
                    x => x, (c, s) => 
                                new Country 
                                {
                                  CID = c.CID, 
                                  Servers =  s.ToList()});

然而,我不相信这符合你们的意愿。

If you can guarantee that the Country object will always contain all Servers, you can could use the following:

var countries = list.SelectMany(s => s.Country).Distinct();

或者,如果您的<代码>,则 does 执行<条码>

var groupBy = list.GroupBy(x => x.Country).Select(x => x.Key);




相关问题
Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How do I compare two decimals to 10 decimal places?

I m using decimal type (.net), and I want to see if two numbers are equal. But I only want to be accurate to 10 decimal places. For example take these three numbers. I want them all to be equal. 0....

Exception practices when creating a SynchronizationContext?

I m creating an STA version of the SynchronizationContext for use in Windows Workflow 4.0. I m wondering what to do about exceptions when Post-ing callbacks. The SynchronizationContext can be used ...

Show running instance in single instance application

I am building an application with C#. I managed to turn this into a single instance application by checking if the same process is already running. Process[] pname = Process.GetProcessesByName("...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...

热门标签