0

在 LINQ 和 lambda 表达式方面,我有点新手,我希望有人能帮助我。

我正在做的是从 ADO.NET SqlDataReader 创建一个聚合对象,响应中有多个数据“表”。

记录集如下所示:

Foo
FooId
...其他描述性字段

Bar
BarId
FooId
...其他描述性字段

Baz
BazId
BarId
...其他描述性字段

我正在遍历每个数据表,一次一个。处理完第一个表后,我拥有了所有的“Foos”,然后第二个是“Bars”,我可以毫无困难地将其关联到“Foo”。(一个“Bar”可以分配给多个 Foo)。

我正在补水的对象是一个列表(为了通过 Web 服务返回它),对象看起来像这样(伪代码):

class Foo
{
  int FooId
  string Name
  string etc
  string YouGetTheIdea
  List<Bar> Bars
}

class Bar
{
  int BarId
  string etc
  List<Baz> Bazes
}

class Baz
{
  int BazId
  string etc
}

到目前为止,我很好。我遇到麻烦的地方是“Bar”对象有一个“Baz”对象列表,这些对象可以附加到多个“Bar”(反过来可以附加到多个“Foo”)

到目前为止,我的代码看起来像这样。如果有更好的方法来解决这个问题,请告诉我。 我的麻烦是,当我进入处理“Baz”的部分时,我不确定如何选择所有“Bar”对象(在具有该 Id 的 Bar 的任何 Foo 下),因此我可以将当​​前 BazId 添加到它的Baz 对象列表。 我目前在这里所拥有的东西在运行时会爆炸,所以这显然是不对的。

using (SafeDataReader reader = this.ExecSPReader(SP_NAME, parms.ToArray()))
{
    if (reader != null)
    {
        // deal with Foos
        while (reader.Read())
        {
            Foo o = new Foo();
            o.FooID = reader.GetInt64("FooID");
            o.Etc = reader.GetString("etc");
            //...more properties
            fooList.Add(o);
        }

        // deal with Bars
        reader.NextResult();
        while (reader.Read())
        {
            Bar p = new Bar();
            long BarFooID = reader.GetInt64("FooID");

            p.BarID = reader.GetInt64("BarID");
            //...more properties

            // find Foo that has this Bar and add to it
            Foo o = fooList.Find(x => x.FooID == barFooID);
            if (o != null)
            {
                if (o.Bars == null)
                {
                    o.Bars = new List<Bar>();
                }
                o.Bars.Add(p);
            }
        }
/*
***
***  Up to here, everything is fine
***  ...but now we need to assign the baz elements to bars, which can belong 
***     to any/all Foos
***
*/
        // deal with Bazs
        reader.NextResult();
        while (reader.Read())
        {
            long bazID = reader.GetInt64("BazID");
            long barID = reader.GetInt64("BarID");

            // here is the problem, ideally I'd like to get a list of all Bar elements with
            // the BarID from the datarow, but not sure how to do that -- the below foreach
            // line errors at runtime
            foreach(Bar p in fooList.Select(a => a.Bars.Where(b => b.BarID == barID)))
            {
                if (p.Bazes == null)
                {
                    p.Bazes = new List<Baz>();
                }
                p.Bazes.Add(bazID);
            }
        }
    }
}

非常感谢任何帮助。

4

1 回答 1

2

使用SelectMany (MSDN)

foreach(Bar p in fooList.SelectMany(a => a.Bars.Where(b => b.BarID == barID)))
            {
                if (p.Bazes == null)
                {
                    p.Bazes = new List<Baz>();
                }
                p.Bazes.Add(bazID);
            }

更新为 a.Bars 可能为空;

foreach(Bar p in fooList.Where(a => a.Bars !=null).SelectMany(a => a.Bars.Where(b => b.BarID == barID)))
            {
                if (p.Bazes == null)
                {
                    p.Bazes = new List<Baz>();
                }
                p.Bazes.Add(bazID);
            }
于 2013-08-21T20:35:09.493 回答