【问题标题】:Linq Join: Join using a mapping table and associate objectsLinq Join:使用映射表连接并关联对象
【发布时间】:2015-04-01 16:54:07
【问题描述】:

我正在尝试编写一个 linq 查询来进行非常基本的连接。我有两个数组

Park[] parks = new Park[]{
                new Park() {ID = 1, Name = "Free Park"},
                new Park() {ID = 2, Name = "Cost Park"},
                new Park() {ID = 3, Name="Sneak in Park"}
};

Facility[] facilities = new Facility[] {
                new Facility() { ID = 1, Name = "Swing", MinimumAge = 1, MaximumAge = 120},
                new Facility() { ID = 2, Name = "Slide", MinimumAge = 1, MaximumAge = 200},
                new Facility() { ID = 3, Name = "See-Saw", MinimumAge = 1, MaximumAge = 300}
};

每个公园可以有0...n设施,因此我们有一组映射对象

ParkFacility[] associations = new ParkFacility[] {
                new ParkFacility() {ParkID = 1, FacilityID = 1},
                new ParkFacility() {ParkID = 1, FacilityID = 2},
                new ParkFacility() {ParkID = 1, FacilityID = 3},
                new ParkFacility() {ParkID = 2, FacilityID = 1},
                new ParkFacility() {ParkID = 3, FacilityID = 2}
};

这是Park类的定义

class Park
{
        public int ID { get; set; }
        public String Name { get; set; }
        public Facility[] Facilities { get; set; }
}

是否可以仅使用连接并将适当的设施与公园相关联?即将 Park 中的 Facilities 数组设置为使用 associations 适当映射的数组?

编辑:到目前为止我的研究..

var x_temp = from g in parks
             join j in associations on g.ID equals j.ParkID into h
             select new Park()
             {
                Name = g.Name,
                ID = g.ID,
                Facilities = (from u in h join m in facilities on u.FacilityID equals m.ID select m).ToArray()
             };

我尝试使用 sub-linq 查询并且它可以工作,但我正在寻找一个只有 连接的解决方案

【问题讨论】:

  • 到目前为止您尝试过什么?您当前尝试使用Join 时遇到了什么问题?您对如何使用Join 操作进行了哪些研究,具体而言,它如何未能帮助您解决问题。
  • 添加了它,我会及时通知你更多我的工作:)

标签: c# linq join


【解决方案1】:

您可以创建从公园 ID 到设施的查找,并使用它来填充每个 Park 对象的 Facilities 属性。请注意,执行此操作的最佳位置是在 Park 的构造函数中,但根据您现有的代码,此 sn-p 将在对象初始化器中执行此操作:

var lookup = associations.ToLookup(pf => pf.ParkID, pf => facilities.Single(f => f.ID == pf.FacilityID));
Park[] parks = new Park[]{
    new Park() {ID = 1, Name = "Free Park", Facilities = lookup[1].ToArray()},
    new Park() {ID = 2, Name = "Cost Park", Facilities = lookup[2].ToArray()},
    new Park() {ID = 3, Name="Sneak in Park", Facilities = lookup[3].ToArray()}
};

此外,将所有FacilityPark 实例存储在将ID 映射到实例的Dictionary 中会很有帮助。在这种情况下,您的查找不需要对每个关联的所有设施进行线性扫描。

【讨论】:

  • 我认为您的解决方案很时尚! :D,不过我有一个问题,如果我在 3 个具有相同概念的 SQL 表(使用 ADO.NET)上使用它会发生什么?会不会有效率?
  • @Lordbalmon 我不知道,您必须衡量它是否适合您的用例。就像我在答案中提到的那样,使用由实体 ID 索引的数据结构将显着改进此代码。如果您使用Dictionary<int, Facility> 来存储设施,则可以将facilities.Single(f => f.ID == pf.FacilityID) 替换为facilities[pf.ID],这是O(n)O(1) 的区别。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 2016-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-10
  • 1970-01-01
相关资源
最近更新 更多