[Linq to Sql] Meerdere zoekwaarden met LIKE *

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • BulMi
  • Registratie: April 2006
  • Laatst online: 10-09 03:49
Ik ben bezig om in een applicatie voor het eerst Linq to sql te gebruiken(alleen jammer dat MS het niet verder gaat uitwerken, maar alle aandacht op het Entity framework gaat zetten, dat i.v.m NHibernate nog erg onvolwassen is). Tot nu toe werkt linq to sql namelijk wel lekker. Maar loop nu tegen een probleem aan.

Voor een website wil ik het mogelijk maken om op redelijk veel velden te kunnen zoeken. En dan ook nog op meerdere waardes. Daarnaast is het ook een match als een deel van de zoekwaarde in het hele woord voorkomt.

Mijn eerste opzet is dat ik in mijn Dataacces methode(waar ik Linq gebruik) een List<string> binnen krijg met daarin alle ingevoerde zoekwaarden van het zoekveld op de webpagina. In het onderstaande code voorbeeld weet ik echter niet wat ik bij de ???? moet invullen. Als het 1 zoekwaarde was zou het een .Contains(zoekwaarde) zijn. Omdat deze volgens mij gelijk staat aan de sql like %zoekwaarde%. Maar hoe ga ik dat doen met meerdere zoekwaarden waar het aantal elke keer anders is?
code:
1
2
3
4
5
6
7
8
9
10
internal static Business.Model.Collections.ProductList Zoeken(List<string> zoekwaardes)
{
var query = (from p in db.Products
where p.Naam.Contains?????
|| p.Omschrijving.Contains????
|| p.Merk.Naam.Contains ????
select p)

return ConvertToBusiness(query);
}

Acties:
  • 0 Henk 'm!

Verwijderd

.Contains(value) is niet gelijk aan 'LIKE %value%' maar meer aan 'value IN (....)'.
linkje

Acties:
  • 0 Henk 'm!

  • mOrPhie
  • Registratie: September 2000
  • Nu online

mOrPhie

❤️❤️❤️❤️🤍

Je moet het om te beginnen omdraaien:

C#:
1
2
3
4
5
6
var query = 
    (from p in db.Products
    where zoekwaardes.Contains(p.Naam) ||
          zoekwaardes.Contains(p.Omschrijving) ||
          zoekwaardes.Contains(p.Merk)
    select p)


Je moet LINQ schrijven met in het achterhoofd "voor elk element uit de lijst X geldt dat ....". Dat is vrij simpele predicaten-logica. :)

Wat AfterLife zegt, klopt trouwens. Bovenstaande query levert wel op wat je wilt, maar dan zonder 'LIKE'. De vraag is of iemand bijvoorbeeld alleen de eerste 3 letters van een naam in zou mogen vullen. Dan moet je nog iets slims doen met de query.

[ Voor 50% gewijzigd door mOrPhie op 01-11-2008 12:10 ]

Een experimentele community-site: https://technobabblenerdtalk.nl/. DM voor invite code.


Acties:
  • 0 Henk 'm!

  • BulMi
  • Registratie: April 2006
  • Laatst online: 10-09 03:49
Ik heb het nog niet getest, maar dacht door deze site dat het wel een like met %% zou zijn:
http://davidhayden.com/bl...eratingLIKESQLServer.aspx


De optie om het om te draaien heb ik ook aan gedacht, maar ik had het vermoeden dat linq dan alle tabellen eerst zou ophalen en in het geheugen zelf de contains uitvoert. En dan zou het inderdaad niet een like zijn. Dit is dan ook wel weer op te lossen door geen contains maar indexOf te gebruiken.

Maar ik hoopte meer op een oplossing waardoor ik niet eerst de hele tabel in het geheugen hoef te laden.

Acties:
  • 0 Henk 'm!

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 10-09 20:32
Als je dat zeker wilt weten dan moet je gewoon eens kijken welke query linq op de achtergrond uitvoert, dan weet je of je vermoeden juist is. Ik vermoed namelijk van niet. Volgens mij doet LinqToSql op de achtergrond al een hoop optimalisatie. Maargoed echt een bron heb ik daar zo niet voor..

* D-Raven gaat ook maar eens profilen..

edit:
Geen IDE bij de hand aangezien mn laptop aan een infuus ligt, dus ik heb ff gegoogled. Misschien dat je met deze info even snel kan achterhalen wat de query is.

linky

[ Voor 26% gewijzigd door D-Raven op 01-11-2008 22:11 ]


Acties:
  • 0 Henk 'm!

  • BulMi
  • Registratie: April 2006
  • Laatst online: 10-09 03:49
Hmm ik heb geen rechten om te profilen op de testdatabase bij mijn provider.

Ik heb wel een linq gevonden met naar mijn idee een nette oplossing :
http://talentgrouplabs.co...-where-clause-part-2.aspx
In deel 1 worden er nog een paar strings aan elkaar geplakt, maar deze methode in deel 2 is zelfs typesafe.

Vanmiddag heb ik de andere optie die hierboven beschreven staat ook nog even getest (zoekwaarde.indexof) Echter na 5 heb ik het stop gezet omdat het nog steeds bezig was met query uitvoeren.

Het blijft een gok omdat profiler bij mij ook nog even niet mogelijk is. Maar met de kleine test die ik gedaan hebt lijkt deze site toch gelijk te hebben :
http://davidhayden.com/bl...eratingLIKESQLServer.aspx En er dus een like %% te worden uitevoerd
Mijn vermoeden is dan ook nog steeds dat zolang linq je code naar een query voor sql kan omzetten het wordt uitgevoerd als een database like met %%. Maar als het te moeilijk wordt(bijv. zoekwaarse.contains()) Dan wordt het grootste deel in het geheugen uitgevoerd (dus alles uit de database opgehaald) en werkt de contains als de contains op een standaard string in c#

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Zet je datacontext.Log op Console.Out en je ziet toch de query?

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Google zoeken op predicate builder voor linq to sql. Dan die class gebruiken voor het aan elkaar plakken van p.Field.Contains(string_uit_zoekwaardes) predicates (met or)

dit gaat wel uit de klauwen lopen bij veel velden * veel zoekwaardes. Maar Linq to Sql ondersteunt geen full-text-search, alhoewel je dat wellicht kunt toevoegen middels een functionmapping op sqlserver 2005's CONTAINS

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Wat misschien ook interessant voor je is is de visual linq query builder.

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Grappig. Je weet zelf niet waarop je zoekt en dan geef je linq to sql daar de schuld van. Vraagje: Kun je hetgeen wat je wilt zelf in een 'normale' T-SQL query schrijven?

Zo ja, dan kun je natuurlijk ook gebruik maken van db.ExecuteQuery<Product>(dbProductSelectQuery);

Linq to sql gebruikt intern dezelfde functie om de resultaten op te halen op het moment dat je een IEnumerable result doorloopt.

Een andere mogelijkheid is dat je 'complexe' queries in een stored procedure plaats en deze SP vervolgens als method van de DataContext toevoegt. Wat op zich natuurlijk al een best practice is..

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Niemand_Anders schreef op maandag 03 november 2008 @ 09:14:
Een andere mogelijkheid is dat je 'complexe' queries in een stored procedure plaats en deze SP vervolgens als method van de DataContext toevoegt. Wat op zich natuurlijk al een best practice is..
Een proc gebruiken een 'best practise' ? Sinds wanneer? Omdat MS het zegt? Ja duh, die willen dat je db specific proc code gaat schrijven, zodat je code nooit portable is naar andere db's.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

EfBe schreef op maandag 03 november 2008 @ 13:55:
[...]

Een proc gebruiken een 'best practise' ? Sinds wanneer? Omdat MS het zegt? Ja duh, die willen dat je db specific proc code gaat schrijven, zodat je code nooit portable is naar andere db's.
Neen maar het is wel gemakkelijker om code portable te maken.

En het is veel beter om die filter op u db uit te voeren, dan tig rows naar u client te sturen en daarop te filteren.

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • TheNameless
  • Registratie: September 2001
  • Laatst online: 07-02 21:38

TheNameless

Jazzballet is vet!

Misschien dat je wat nuttigs vind in System.Data.Linq.SqlClient.SqlMethods :)

edit: nm, CONTAINS doet hetzelfde zie ik

[ Voor 20% gewijzigd door TheNameless op 03-11-2008 14:21 ]

Ducati: making mechanics out of riders since 1946


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

EfBe schreef op maandag 03 november 2008 @ 13:55:
Een proc gebruiken een 'best practise' ? Sinds wanneer? Omdat MS het zegt? Ja duh, die willen dat je db specific proc code gaat schrijven, zodat je code nooit portable is naar andere db's.
Wat je nu soms gaan beweren dat Oracle en MySQL soms geen stored procedures kennen? Stored Procedures zijn zelfs onderdeel van de SQL-92 specificaties (hoofstuk 4.17).

Stored Procedures maken *JUIST* je code portable omdat de database specifieke onderdelen in de procedure zitten in niet meer in je access layer. Voor mijn code is er dan geen verschil of de stored procedure GetProductsBySearch wordt uitgevoerd op een Oracle of MySQL database. Wat er in die stored procedure gebeurt kan ik per database aanpassen c.q. optimaliseren..

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • rrrandy
  • Registratie: Juli 2005
  • Laatst online: 27-06 13:00
Niemand_Anders schreef op maandag 03 november 2008 @ 17:04:
[...]

Wat je nu soms gaan beweren dat Oracle en MySQL soms geen stored procedures kennen? Stored Procedures zijn zelfs onderdeel van de SQL-92 specificaties (hoofstuk 4.17).

Stored Procedures maken *JUIST* je code portable omdat de database specifieke onderdelen in de procedure zitten in niet meer in je access layer. Voor mijn code is er dan geen verschil of de stored procedure GetProductsBySearch wordt uitgevoerd op een Oracle of MySQL database. Wat er in die stored procedure gebeurt kan ik per database aanpassen c.q. optimaliseren..
M.a.w. het ligt er dus maar net aan welke code je bedoelt :)

Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Snake schreef op maandag 03 november 2008 @ 14:17:
[...]

Neen maar het is wel gemakkelijker om code portable te maken.

En het is veel beter om die filter op u db uit te voeren, dan tig rows naar u client te sturen en daarop te filteren.
Dat kan toch ook gewoon met een linq query? Een proc die variabele lijsten accepteert ziet er ook niet best uit, dus het is lood om oud ijzer: of je bakt een linq query die in een reeks LIKE OR predicates resulteert, OF je bakt een proc die met string concatenation / splitting (want sqlserver ondersteunt geen array parameters, althans 2005 en eerder) de zaak te lijf gaat, maar veel schiet je daar niet mee op.

@niemand_anders
Als jij je T-SQL procs 1:1 kunt porten naar PL/SQL dan ben je erg goed, want dat gaat je echt niet lukken zonder veel rewrites. En _ZEKER_ een proc die variabele lists van strings accepteert waarop gezocht moet worden over meerdere fields. Maar we dwalen af.

[ Voor 16% gewijzigd door EfBe op 03-11-2008 17:32 ]

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

[quote]EfBe schreef op maandag 03 november 2008 @ 17:31:
@niemand_anders
Als jij je T-SQL procs 1:1 kunt porten naar PL/SQL dan ben je erg goed, want dat gaat je echt niet lukken zonder veel rewrites. En _ZEKER_ een proc die variabele lists van strings accepteert waarop gezocht moet worden over meerdere fields. Maar we dwalen af.
Laat ik voorop stellen dat ik nooit stored procedures port, maar hun functionaliteit. En die functionaliteit is (bij ons) eigenlijk meestal heel erg beperkt: Of je haalt records op (select) of je wijzigd ze (insert, update, delete).

Het wordt wel een stuk lastiger als je managed stored procedures op de database gaat gebruiken. Oracle en/of PostgreSQL hebben dan nog wel support voor java based stored procedures, maar porten blijft dan lastig. Maar als je je database objecten aan de hand van SQL-92 beschrijft, dan mag je eigenlijk geen problemen tegenkomen bij het porten..

If it isn't broken, fix it until it is..

Pagina: 1