Lad os saa se paa de forkerte maader.
En ganske lille aendring af database oprettelse er nok til at bring os i problemer:
CREATE TABLE badparent (
id INTEGER NOT NULL,
fulnam VARCHAR(20),
PRIMARY KEY(id)
)
GO
CREATE TABLE badchild (
id INTEGER NOT NULL,
val INTEGER,
parent_id INTEGER,
PRIMARY KEY(id)
)
GO
INSERT INTO badparent VALUES (1, 'A')
GO
INSERT INTO badparent VALUES (2, 'BB')
GO
INSERT INTO badparent VALUES (3, 'CCC')
GO
INSERT INTO badchild VALUES (11, 101, 1)
GO
INSERT INTO badchild VALUES (12, 102, 1)
GO
INSERT INTO badchild VALUES (21, 103, 2)
GO
Eneste forskel er at vi har fjernet foreign key constraint.
SQL virker fuldstaendigt ligesom foer.
Men ved kode generering, saa faar badparent ikke association/aggregration til badchild.
Og saa er det lige pludseligt lidt vanskeligere.
Og man ender hurtigt med noget spagetti kode.
Jeg synes at foelgende kode er rimelig laeselig (det er ikke sikker at den er hurtigst):
public class Workaround : badparent
{
public IEnumerable<badchild> badchild;
}
...
// bad workaround
using(EF_LINQContext ctx = new EF_LINQContext())
{
IQueryable<Workaround> q = ctx.badparent.GroupJoin(ctx.badchild,
bp => bp.id,
bc => bc.parent_id,
(bp, allbc) => new Workaround{ id = bp.id, fulnam = bp.fulnam, badchild = allbc });
foreach(Workaround w in q)
{
Console.Write("{0,3} {1,-10}:", w.id, w.fulnam);
foreach(badchild bc in w.badchild)
{
Console.Write(" {0}", bc.val);
}
Console.WriteLine();
}
}
Det virker. Og jeg kan godt lide at man ligesom simulerer den rigtige loesning!
Du rendte saa ind i problemet at du ikke rigtigt kunne noget med to data context'er.
Men det problem er nemt at fixe. Bare materialiser dine queries, saa skifter du fra LINQ to EF til LINQ to Objects og saa har du ikke noget problem.
(ved store data maengder vil performance dog maaske give et problem)
// bad two context workaround
using(EF_LINQContext pctx = new EF_LINQContext())
using(EF_LINQContext cctx = new EF_LINQContext())
{
IEnumerable<Workaround> q = pctx.badparent.ToList().GroupJoin(cctx.badchild.ToList(),
bp => bp.id,
bc => bc.parent_id,
(bp, allbc) => new Workaround{ id = bp.id, fulnam = bp.fulnam, badchild = allbc });
foreach(Workaround w in q)
{
Console.Write("{0,3} {1,-10}:", w.id, w.fulnam);
foreach(badchild bc in w.badchild)
{
Console.Write(" {0}", bc.val);
}
Console.WriteLine();
}
}