[LINQ] Query voor 1-op-veel relatie

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Marcel317
  • Registratie: December 2012
  • Laatst online: 14-07 17:08
Hallo allen,


Ik heb een aantal tabellen:
  • Voorwaarden
  • Producten
  • Koppeltabel die 'Voorwaarden' en 'Producten' aan elkaar koppelt d.m.v. elkaars ID
  • Verzekeraar
De situatie is zo;
Een Verzekeraar heeft meerdere Producten. Verzekeraars zijn gelinkt aan Producten d.m.v. ID (FK)
Producten zijn vervolgens gelinkt aan bepaalde Voorwaarden.

Wat ik moet hebben is;
Een LINQ query die alle Voorwaarden ophaalt voor de Producten die van toepassing zijn op de Verzekeraar.

Ik vermoed dat ik echt compleet verkeerd bezig ben of in ieder geval via een flinke omweg. Dit heb ik nu;
code:
1
2
3
4
5
6
7
8
var voorwaarden = from vw in zvData.pdfs
where vw.id == (from vwpr in zvData.pdf_products
              from prId in zvData.products
              where prId.id == (from pr in zvData.products
                                where pr.insurance_provider_id == item
                                select pr.id)
              select vwpr.pdf_id)
select vw.filename;


Kunnen jullie wat suggesties aandragen? Aangezien ik compleet vast zit.

[ Voor 13% gewijzigd door RobIII op 03-01-2013 12:49 . Reden: Code leesbaar gemaakt ]


Acties:
  • 0 Henk 'm!

  • HMS
  • Registratie: Januari 2004
  • Laatst online: 16-07 23:57

HMS

Gebruik je een ORM als NHibernate / Entity Framework? Of gebruik je LINQ-to-SQL?

Afhankelijk van je model zou iets dit moeten voldoen:

C#:
1
2
var verzekeraar = Verzekeraars.Get(item);
var voorwaarden = verzekeraar.Products.SelectMany(x => x.Voorwaarden);


Als dit niet kan, dan zul je met meerdere queries (of een Prepared Statement OID) het volgende moeten doen (je LINQ query snapte ik niet helemaal, maar iets in deze lijn zou het moeten zijn):
C#:
1
2
3
4
5
6
7
8
9
10
11
var insurerProducts = from pr in zvData.products
                       where pr.insurance_provider_id == item
                       select pr.id);

var productVoorwaarden = from vwpr in zvData.pdf_products
                          where insurerProducts.Contains(vwpr.Id)
                          select vwpr.pdf_id;

var voorwaarden = from vw in vzData.pdfs
                  where productVoorwaarden.Contains(vw.id)
                  select vw.filename;

Acties:
  • 0 Henk 'm!

Anoniem: 198334

Je zit vast zeg je.

Wat is dan het probleem?
Je krijgt een exception?
Je krijgt te veel? Je krijgt te weinig? Je krijgt de voorwaarden van een verkeerde verzekeraar?

Gelieve je probleem wat beter te beschrijven.

Acties:
  • 0 Henk 'm!

  • Marcel317
  • Registratie: December 2012
  • Laatst online: 14-07 17:08
Anoniem: 198334 schreef op donderdag 03 januari 2013 @ 12:46:
Je zit vast zeg je.

Wat is dan het probleem?
Je krijgt een exception?
Je krijgt te veel? Je krijgt te weinig? Je krijgt de voorwaarden van een verkeerde verzekeraar?

Gelieve je probleem wat beter te beschrijven.
Excuses. Ik krijg niets. Wat ik geschreven had (wat zoals ik zei ongetwijfeld niet de juiste manier is) zorgt ervoor dat ik een exception krijg.

Logisch, aangezien er een single int vergeleken wordt met een IQueryable int. Verder dan dat kom ik eigenlijk niet.

Acties:
  • 0 Henk 'm!

  • Marcel317
  • Registratie: December 2012
  • Laatst online: 14-07 17:08
Ik ben eruit. Ik heb de code van HMS gepakt en het werkt nu perfect.
Dank jullie wel voor de snelle hulp.

Acties:
  • 0 Henk 'm!

  • HMS
  • Registratie: Januari 2004
  • Laatst online: 16-07 23:57

HMS

Die code werkt misschien wel, maar ik zou als ik jou was toch op een paar dingen letten.

1. De SQL die daar uit komt zal waarschijnlijk niet super snel zijn qua performance
2. Contains query's worden vertaald naar een IN ( ) in SQL, als je veel parameters hebt dan kan dit voor exceptions zorgen (dus als producten / voorwaarden hebt dan kan het crashen). Volgens mij zit die grens ergens bij de 3000 of 4000.
3. Misschien ben je wel sneller af met behulp van JOINS o.i.d. Mijn SQL is vrij roestig sinds ik NHibernate alles laat op lossen / sinds ik andere opslag methodes gebruik ;)

Acties:
  • 0 Henk 'm!

  • Marcel317
  • Registratie: December 2012
  • Laatst online: 14-07 17:08
HMS schreef op donderdag 03 januari 2013 @ 13:23:
Die code werkt misschien wel, maar ik zou als ik jou was toch op een paar dingen letten.

1. De SQL die daar uit komt zal waarschijnlijk niet super snel zijn qua performance
2. Contains query's worden vertaald naar een IN ( ) in SQL, als je veel parameters hebt dan kan dit voor exceptions zorgen (dus als producten / voorwaarden hebt dan kan het crashen). Volgens mij zit die grens ergens bij de 3000 of 4000.
3. Misschien ben je wel sneller af met behulp van JOINS o.i.d. Mijn SQL is vrij roestig sinds ik NHibernate alles laat op lossen / sinds ik andere opslag methodes gebruik ;)
Correct me if I'm wrong maar; het handige/nuttige van LINQ to SQL is toch juist dat JOINS eigenlijk niet meer nodig zijn? (Aangezien de *.dbml file die relaties al legt/snapt)

Acties:
  • 0 Henk 'm!

  • HMS
  • Registratie: Januari 2004
  • Laatst online: 16-07 23:57

HMS

Het nuttige van een ORM is dat je je niet meer bezig hoeft te houden met SQL (simpel gezegd).

Achter de schermen doet een ORM gewoon SQL queries, en dus ook JOINS. Een JOIN blijft een makkelijk (en goede) manier om 1-op-veel relaties op te halen.

LINQ to SQL is echter een zeer beperkte ORM, en het gebruik ervan zou ik ook afraden. Voor nieuwe projecten zou ik naar NHibernate of Entity Framework kijken, die ondersteunen ook gewoon LINQ maar zijn veel geavanceerder.

Wiki: Wikipedia: Object-relational mapping

[ Voor 10% gewijzigd door HMS op 03-01-2013 13:51 ]

Pagina: 1