From: shapper on
Hello,

I am trying to create a Many to Many relationship using XML files:

<As>
<A>
<Id>1</Id>
</A>
<A>
<Id>2</Id>
</A>
<As>

<ABs>
<AB>
<AId>1</AId>
<BId>1</BId>
</AB>
<AB>
<AId>2</AId>
<BId>1</BId>
</AB>
<ABs>

<Bs>
<B>
<Id>1</Id>
</B>
<B>
<Id>2</Id>
</B>
<Bs>

And my objects are simply:

public class A {
public Int32 Id { get; set; }
public IList<B> Bs { get; set; }
}

public class B {
public Int32 Id { get; set; }
}

Basically, I need to create a List of objects A and for each fill the
Bs in each A.

return _As.Root.Elements("A").Select(u => new A {
Id = Int32.Parse(u.Element("Id").Value),
Bs = _ABs.Root.Elements("AB"). //?????
}).AsList();

Where _As, _ABs and _Bs are XDocuments loaded from the 3 XML files.

How can I fill Bs for each A?

Thanks,
Miguel
From: Arne Vajhøj on
shapper wrote:
> I am trying to create a Many to Many relationship using XML files:
>
> <As>
> <A>
> <Id>1</Id>
> </A>
> <A>
> <Id>2</Id>
> </A>
> <As>
>
> <ABs>
> <AB>
> <AId>1</AId>
> <BId>1</BId>
> </AB>
> <AB>
> <AId>2</AId>
> <BId>1</BId>
> </AB>
> <ABs>
>
> <Bs>
> <B>
> <Id>1</Id>
> </B>
> <B>
> <Id>2</Id>
> </B>
> <Bs>
>
> And my objects are simply:
>
> public class A {
> public Int32 Id { get; set; }
> public IList<B> Bs { get; set; }
> }
>
> public class B {
> public Int32 Id { get; set; }
> }
>
> Basically, I need to create a List of objects A and for each fill the
> Bs in each A.
>
> return _As.Root.Elements("A").Select(u => new A {
> Id = Int32.Parse(u.Element("Id").Value),
> Bs = _ABs.Root.Elements("AB"). //?????
> }).AsList();
>
> Where _As, _ABs and _Bs are XDocuments loaded from the 3 XML files.
>
> How can I fill Bs for each A?

There are probably many ways of doing that.

For one of them see below.

(note that I am not really using bxml/bdoc, because there are no need
in this example)

Arne

=====================================

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace E
{
public class A {
public Int32 Id { get; set; }
public IList<B> Bs { get; set; }
}
public class B {
public Int32 Id { get; set; }
}
public class Program
{
public static void Main(string[] args)
{
string axml = @"<As>
<A>
<Id>1</Id>
</A>
<A>
<Id>2</Id>
</A>
</As>";
string bxml = @"<Bs>
<B>
<Id>1</Id>
</B>
<B>
<Id>2</Id>
</B>
<B>
<Id>3</Id>
</B>
</Bs>";
string abxml = @"<ABs>
<AB>
<AId>1</AId>
<BId>1</BId>
</AB>
<AB>
<AId>2</AId>
<BId>1</BId>
</AB>
<AB>
<AId>2</AId>
<BId>3</BId>
</AB>
</ABs>";
XDocument adoc = XDocument.Parse(axml);
XDocument bdoc = XDocument.Parse(bxml);
XDocument abdoc = XDocument.Parse(abxml);
List<A> alst = new List<A>();
foreach(int aid in from a in adoc.Root.Elements("A") select
int.Parse(a.Element("Id").Value))
{
alst.Add(new A { Id=aid, Bs=(from b in
abdoc.Root.Elements("AB") where int.Parse(b.Element("AId").Value)==aid
select new B { Id=int.Parse(b.Element("BId").Value) }).ToList() });
}
foreach(A aelm in alst)
{
Console.WriteLine(aelm.Id);
foreach(B belm in aelm.Bs)
{
Console.Write(" " + belm.Id);
}
Console.WriteLine();
}
Console.ReadKey();
}
}
}
From: shapper on
On Nov 10, 12:41 am, Arne Vajhøj <a...(a)vajhoej.dk> wrote:
> shapper wrote:
> > I am trying to create a Many to Many relationship using XML files:
>
> > <As>
> >   <A>
> >     <Id>1</Id>
> >   </A>
> >   <A>
> >     <Id>2</Id>
> >   </A>
> > <As>
>
> > <ABs>
> >   <AB>
> >     <AId>1</AId>
> >     <BId>1</BId>
> >   </AB>
> >   <AB>
> >     <AId>2</AId>
> >     <BId>1</BId>
> >   </AB>
> > <ABs>
>
> > <Bs>
> >   <B>
> >     <Id>1</Id>
> >   </B>
> >   <B>
> >     <Id>2</Id>
> >   </B>
> > <Bs>
>
> > And my objects are simply:
>
> > public class A {
> >   public Int32 Id { get; set; }
> >   public IList<B> Bs { get; set; }
> > }
>
> > public class B {
> >   public Int32 Id { get; set; }
> > }
>
> > Basically, I need to create a List of objects A and for each fill the
> > Bs in each A.
>
> >       return _As.Root.Elements("A").Select(u => new A {
> >         Id = Int32.Parse(u.Element("Id").Value),
> >         Bs = _ABs.Root.Elements("AB"). //?????
> >       }).AsList();
>
> > Where _As, _ABs and _Bs are XDocuments loaded from the 3 XML files.
>
> > How can I fill Bs for each A?
>
> There are probably many ways of doing that.
>
> For one of them see below.
>
> (note that I am not really using bxml/bdoc, because there are no need
> in this example)
>
> Arne
>
> =====================================
>
> using System;
> using System.Collections.Generic;
> using System.Linq;
> using System.Xml.Linq;
>
> namespace E
> {
>      public class A {
>          public Int32 Id { get; set; }
>          public IList<B> Bs { get; set; }
>      }
>      public class B {
>          public Int32 Id { get; set; }
>      }
>      public class Program
>      {
>          public static void Main(string[] args)
>          {
>              string axml = @"<As>
>    <A>
>      <Id>1</Id>
>    </A>
>    <A>
>      <Id>2</Id>
>    </A>
> </As>";
>              string bxml = @"<Bs>
>    <B>
>      <Id>1</Id>
>    </B>
>    <B>
>      <Id>2</Id>
>    </B>
>    <B>
>      <Id>3</Id>
>    </B>
> </Bs>";
>              string abxml = @"<ABs>
>    <AB>
>      <AId>1</AId>
>      <BId>1</BId>
>    </AB>
>    <AB>
>      <AId>2</AId>
>      <BId>1</BId>
>    </AB>
>    <AB>
>      <AId>2</AId>
>      <BId>3</BId>
>    </AB>
> </ABs>";
>              XDocument adoc = XDocument.Parse(axml);
>              XDocument bdoc = XDocument.Parse(bxml);
>              XDocument abdoc = XDocument.Parse(abxml);
>              List<A> alst = new List<A>();
>              foreach(int aid in from a in adoc.Root.Elements("A") select
> int.Parse(a.Element("Id").Value))
>              {
>                  alst.Add(new A { Id=aid, Bs=(from b in
> abdoc.Root.Elements("AB") where int.Parse(b.Element("AId").Value)==aid
> select new B { Id=int.Parse(b.Element("BId").Value) }).ToList() });
>              }
>              foreach(A aelm in alst)
>              {
>                  Console.WriteLine(aelm.Id);
>                  foreach(B belm in aelm.Bs)
>                  {
>                      Console.Write("  " + belm.Id);
>                  }
>                  Console.WriteLine();
>              }
>              Console.ReadKey();
>          }
>      }
>
> }
>
>

Isn't possible to use Linq to make this query. Just as I use when
using Linq to Sql. Just wondering.

Thanks,
Miguel
From: Arne Vajhøj on
shapper wrote:
> On Nov 10, 12:41 am, Arne Vajh�j <a...(a)vajhoej.dk> wrote:
>> shapper wrote:
>>> I am trying to create a Many to Many relationship using XML files:
>>> <As>
>>> <A>
>>> <Id>1</Id>
>>> </A>
>>> <A>
>>> <Id>2</Id>
>>> </A>
>>> <As>
>>> <ABs>
>>> <AB>
>>> <AId>1</AId>
>>> <BId>1</BId>
>>> </AB>
>>> <AB>
>>> <AId>2</AId>
>>> <BId>1</BId>
>>> </AB>
>>> <ABs>
>>> <Bs>
>>> <B>
>>> <Id>1</Id>
>>> </B>
>>> <B>
>>> <Id>2</Id>
>>> </B>
>>> <Bs>
>>> And my objects are simply:
>>> public class A {
>>> public Int32 Id { get; set; }
>>> public IList<B> Bs { get; set; }
>>> }
>>> public class B {
>>> public Int32 Id { get; set; }
>>> }
>>> Basically, I need to create a List of objects A and for each fill the
>>> Bs in each A.
>>> return _As.Root.Elements("A").Select(u => new A {
>>> Id = Int32.Parse(u.Element("Id").Value),
>>> Bs = _ABs.Root.Elements("AB"). //?????
>>> }).AsList();
>>> Where _As, _ABs and _Bs are XDocuments loaded from the 3 XML files.
>>> How can I fill Bs for each A?
>> There are probably many ways of doing that.
>>
>> For one of them see below.
>>
>> (note that I am not really using bxml/bdoc, because there are no need
>> in this example)
>>
>> Arne
>>
>> =====================================
>>
>> using System;
>> using System.Collections.Generic;
>> using System.Linq;
>> using System.Xml.Linq;
>>
>> namespace E
>> {
>> public class A {
>> public Int32 Id { get; set; }
>> public IList<B> Bs { get; set; }
>> }
>> public class B {
>> public Int32 Id { get; set; }
>> }
>> public class Program
>> {
>> public static void Main(string[] args)
>> {
>> string axml = @"<As>
>> <A>
>> <Id>1</Id>
>> </A>
>> <A>
>> <Id>2</Id>
>> </A>
>> </As>";
>> string bxml = @"<Bs>
>> <B>
>> <Id>1</Id>
>> </B>
>> <B>
>> <Id>2</Id>
>> </B>
>> <B>
>> <Id>3</Id>
>> </B>
>> </Bs>";
>> string abxml = @"<ABs>
>> <AB>
>> <AId>1</AId>
>> <BId>1</BId>
>> </AB>
>> <AB>
>> <AId>2</AId>
>> <BId>1</BId>
>> </AB>
>> <AB>
>> <AId>2</AId>
>> <BId>3</BId>
>> </AB>
>> </ABs>";
>> XDocument adoc = XDocument.Parse(axml);
>> XDocument bdoc = XDocument.Parse(bxml);
>> XDocument abdoc = XDocument.Parse(abxml);
>> List<A> alst = new List<A>();
>> foreach(int aid in from a in adoc.Root.Elements("A") select
>> int.Parse(a.Element("Id").Value))
>> {
>> alst.Add(new A { Id=aid, Bs=(from b in
>> abdoc.Root.Elements("AB") where int.Parse(b.Element("AId").Value)==aid
>> select new B { Id=int.Parse(b.Element("BId").Value) }).ToList() });
>> }
>> foreach(A aelm in alst)
>> {
>> Console.WriteLine(aelm.Id);
>> foreach(B belm in aelm.Bs)
>> {
>> Console.Write(" " + belm.Id);
>> }
>> Console.WriteLine();
>> }
>> Console.ReadKey();
>> }
>> }
>>
>> }
>>
>>
>
> Isn't possible to use Linq to make this query. Just as I use when
> using Linq to Sql. Just wondering.

I am using LINQ.

I guess tht you are asking if the two LINQ's can be replaced
with a single LINQ.

Maybe it can, but at least I can not see how.

But why? Since the XDocument are in memory, then there
are not really any overhead of doing multiple LINQ's.

Arne
From: shapper on
On Nov 10, 2:40 am, Arne Vajhøj <a...(a)vajhoej.dk> wrote:
> But why? Since the XDocument are in memory, then there
> are not really any overhead of doing multiple LINQ's.

Yes,

I was trying to do it in a single Linq query:

IList<A> As = _As.Root.Elements("A").Select(a => new A {
Id = Int32.Parse(u.Element("Id").Value),
Bs = _ABs.Root.Elements("AB")
.Where(ab => ab.Element("Id") == a.Element("Id")).
.Select(ab => _Bs.Root.Elements("B")
.Select(b => new B {
Id = Int32.Parse(b.Element("Id").Value),
Name = b.Element("Id").Value)
}).Where(r => r.Id == ???

I am a little bit confused about your loops.
In my code, I think you are doing it, can't I get (in my Select
statement) the values of Bs which id is equal to ab.

Don't Linq convert into loops internally?
So this should be possible using a single Linq Query.