LINQ GroupBy,将一对一列表转换为一对多
这可以通过一百万种方式来完成......
问题。 我有一个属于某个国家/地区的服务器列表。
国家有很多服务器,所以它是一种双向导航(我认为它被称为)
现在我有一个设置了国家/地区的服务器列表,并希望按国家/地区进行分组,以便我可以获得相反的列表。
国家/地区列表,其中所有服务器都附加到该国家/地区的 ICollection(服务器),
var groupBy = list.GroupBy(x => x.Country, x => x, (c, s) => new {c, s});
foreach (var country in groupBy)
{
}
这几乎会给我我想要的结果,但现在我有 2 种匿名类型。 C 是国家/地区,S 是服务器列表。
如何将服务器列表附加到国家/地区对象的集合中。
类看起来像这样......简化了。
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; }
}
我想人们可以用这些信息创建一个新的国家,然后将服务器列表放入构造函数中......但我认为这有点矫枉过正。
嗯……这很奇怪,很简单,但我在这里迷路了。
更新
我需要选择满足某些条件的所有服务器。这就是为什么我有一个国家/地区的服务器列表。现在我只需要反转列表即可。可以反过来做吗?
我正在使用 EF 4 Code First 的存储库模式。 信息库 我只有以下方法可用,并且可以选择立即加载属性: Single、SingleOrDefault、Find 和 FindAll
没有延迟加载,它们都返回 ICollection 或单个 T。
This can be done in a million ways ...
Problem.
I have a list of servers which belongs to a country.
Countries have many servers, so its a 2 way navigation( I think its called )
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.
Classes look like this... simplified.
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; }
}
I guess one could create a new Country with the information and then also put the list of servers in the constructor ... but that's kind of overkill I think.
Well ... this odd to be simple but I'm lost here.
Update
I need to select all servers that satisfy some condition. That's why I have a list of servers with the country. Now I just need to invert the list. Can this be done the other way around ?
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
There are no lazy load, they all return ICollection or a single T.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
听起来您真的只是想建立一个从国家/地区到服务器的查找:
如果这不是您正在寻找的内容,请告诉我它为什么不能满足您的要求:)
诚然无法保证每个国家/地区都拥有原始列表中的所有服务器,这听起来似乎正是这种区别才是真正的问题。
如果你的
Server
已经设置了Country
,你能不能假设数据已经一致了?如果没有,您的服务器
不应该真的有一个CID而不是国家
参考吗?拥有一个有时与“this”对象一致、有时不一致的属性(即server.Country.Contains(server)
是否保证返回true< /code> 或不是)在我看来是丑陋的。
编辑:好的,一个可能更好的替代方案是:
这与 fermaref 的方法几乎相同,但我明确使用
Country.CID
来避免两台服务器由于可能存在奇怪的平等规则,同等国家/地区最终不会归入同一桶中。It sounds like you really just want to build up a Lookup from country to servers:
If that's not what you're looking for, please let me know how it doesn't do what you want :)
Admittedly there's no guarantee that each
Country
will have all the servers in the original list, and that sounds like it's that distinction which is really the problem.If your
Server
already has theCountry
set, can you not assume that the data is already consistent? If not, shouldn't yourServer
really have a CID instead of aCountry
reference? Having a property which will sometimes be consistent with "this" object and sometimes not (i.e. whetherserver.Country.Contains(server)
is guaranteed to returntrue
or not) is ugly IMO.EDIT: Okay, a possibly nicer alternative is:
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 用于查询,它具有函数式思维,您可以生成新实例而不是修改现有实例。
如果您想修改实例,foreach 循环会更好:
如果您必须使用 Linq:
Linq is for querying and it has a functional mindset where you generate new instances instead of modifying existing instances.
If you want to modify instances, a foreach loop is superior:
If you must use Linq:
如果您不能保证每个
Server
对象中的Country
对象已包含所有服务器,您可以创建一个新的Country
对象:但是,我不确定这是否是你想要的。
如果您可以保证
Country
对象始终包含所有Servers
,则可以使用以下内容:或者,如果您的
Country
不包含实现IEquatable:If you can't guarantee that the
Country
object in eachServer
object already contains all the Servers, you can create a newCountry
object:However, I'm not sure if that's what you want.
If you can guarantee that the
Country
object will always contain allServers
, you can could use the following:or, if your
Country
doesn't implementIEquateable
: