[C#] Linq to Entities naar dubbele zoeken

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 11-09 12:47
Ik heb een database met MP3's (Draaiende op Windows 7, MySQL 5) en deze heb ik gekoppeld aan de entity MP3Record.

Hier staat artiest, title, album etc. in.
In deze table staan ook dubbele in: dus ander path, rest hetzelfde. Ik wil deze zoeken. Dus ik wil een selectie van alle records waar bijvoorbeeld 2 files met dezelfde naam en titel zijn (en dus de file lokatie anders).

Stel ik heb een file van queen met will will rock you op 2 plaatsen staan en ook een file van bzn op 2 plaatsen (met zelfde titel en naam) wil is dus via een query (of meerdere) deze 4 files laten zien.

Ik ben de hele dag aan aan het kloten maar ik zie het echt niet. Hoe krijg je zoeiets voor elkaar?

Met 2 files is het wel te doen (denk ik...), maar wat als het er 3 zijn?

if broken it is, fix it you should


Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 00:41

TeeDee

CQB 241

Ik denk dat je op zoek bent naar een HAVING en een COUNT > 1 variant.

Wat is er mis met een fatsoenlijke 'ontdubbel' query en deze omzetten naar LINQ met de keywords in die 'ontdubbel' query?

[ Voor 105% gewijzigd door TeeDee op 07-12-2009 20:47 ]

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 11-09 12:47
TeeDee schreef op maandag 07 december 2009 @ 20:34:
Ik denk dat je op zoek bent naar een HAVING en een COUNT > 1 variant.

Wat is er mis met een fatsoenlijke 'ontdubbel' query en deze omzetten naar LINQ met de keywords in die 'ontdubbel' query?
Hoe bedoel je?

if broken it is, fix it you should


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
[google=linq get duplicates]? ;)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 00:41

TeeDee

CQB 241

Als het in linq niet lukt, ga je zoeken naar de SQL variant om vervolgens dit om te zetten naar LINQ? Maar misschien kan je beter naar de link van pedorus kijken.

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

  • - peter -
  • Registratie: September 2002
  • Laatst online: 09-09 20:00
Iets met GroupBy()?

Mogelijk dat je kan doen .GroupBy(M => M.titel.ToString() + M.naam.ToString())
Maar ik weet niet of dat met Linq to Entities kan.

Anders kan je zowieso alle records ophalen, met .ToList() naar een List converteren en dan met de gewone LINQ die GroupBy doen. Niet zo efficient enzo, maar het werkt wel.

Vervolgens selecteer je alleen de groups die meer dan 1 member hebben, en dan heb je gelijk ook een match als je bijv. 3 members hebt.

Acties:
  • 0 Henk 'm!

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 11-09 12:47
Het zoeken naar de echte dubbele is geen probleem (inmiddels)

echter wil ik ook ongeveer dezelfde. lees MichEal JaCksOn == macheal jackson. met normale linq in een list oid lukt me dit wel, maar met linq to entitties niet.

if broken it is, fix it you should


Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 00:41

TeeDee

CQB 241

elgringo schreef op dinsdag 08 december 2009 @ 13:13:
Het zoeken naar de echte dubbele is geen probleem (inmiddels)
(Toon die oplossing ook eens... voor het nageslacht!)

En wat heb je nu zelf al gedaan? Ik vermoed dat dit niet zomaar kan met Linq to Entities en dat je een tussenstap moet inbouwen.

[ Voor 49% gewijzigd door TeeDee op 08-12-2009 13:23 ]

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
elgringo schreef op dinsdag 08 december 2009 @ 13:13:
echter wil ik ook ongeveer dezelfde. lees MichEal JaCksOn == macheal jackson. met normale linq in een list oid lukt me dit wel, maar met linq to entitties niet.
Beschrijf dan eerst eens wat je al geprobeerd hebt, en wat er niet wilde lukken.

Verder is het dan handig als je laat zien hoe je het in een in memory list zou oplossen.

Voordat je het in Linq wil implementeren is het misschien ook handig als je er over nadenkt welke SQL query je er voor nodig zou hebben.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Phyxion
  • Registratie: April 2004
  • Niet online

Phyxion

_/-\o_

ToUpper? Ik neem aan dat je zoiets trouwens echt wel kan vinden via G hoor.

'You like a gay cowboy and you look like a gay terrorist.' - James May


Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 00:41

TeeDee

CQB 241

Phyxion schreef op dinsdag 08 december 2009 @ 14:12:
ToUpper? Ik neem aan dat je zoiets trouwens echt wel kan vinden via G hoor.
Daar zat ik ook aan te denken (ToLower) maar ik denk dat het verschil tussen michael en machael het e.e.a. lastig zal maken.

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

  • Phyxion
  • Registratie: April 2004
  • Niet online

Phyxion

_/-\o_

TeeDee schreef op dinsdag 08 december 2009 @ 15:37:
[...]

Daar zat ik ook aan te denken (ToLower) maar ik denk dat het verschil tussen michael en machael het e.e.a. lastig zal maken.
Mja, dat is niet echt te doen, of je moet hele lijst bij gaan houden. Enige wat je misschien nog kan doen is er eerst een filter over gaan gooien die er bepaalde chars uithaalt en dan kijkt hoeveel % iets matched, stel 99% gelijk is een hetzelfde nummer oid.

'You like a gay cowboy and you look like a gay terrorist.' - James May


Acties:
  • 0 Henk 'm!

  • neothor
  • Registratie: Oktober 2004
  • Laatst online: 02-10-2023
Ik zie eigenlijk niet zoveel problemen of ik moet wat over het hoofd zien maar het volgende werkt bij mij.

C#:
1
2
3
var companies = context.Companys
            .GroupBy(c => c.Name.ToUpper())
            .Where(g => g.Count() > 1);    


Eigen entities gebruikt zoals jullie zien ;)

Hmm ik zie nu pas de post van elgringo dat het gelukt is met dit deel van het probleem :o

[ Voor 21% gewijzigd door neothor op 08-12-2009 15:57 . Reden: Niet goed gelezen :x ]

Last.fm | LinkedIn | Twitter


Acties:
  • 0 Henk 'm!

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 11-09 12:47
In code ben ik aan het spelen geweest met toupper() en dan vergelijken, regular expressions en endswith. Ik vond dit regelijk traag.

Vooral als ik dezelfde file zoek, dat als ook wat niet lukt met linq, ik betwijfel ook of het uberhaupt mogelijk is, dus \map1\file.mp3 en \mp2\file.mp3. Deze hebben dezelfde filenaam en kan ik dus ook als 'dubbel' zien.

Met regex is het traag. waarschijnlijk omdat de bestandsnamen erg lang zijn. (met artiesten en titels is hij een stuk sneller).

Als ik het in code oplos moet ik ook n! (met n het aantal records) er door heen. (als het tegen zin en er geen dubbele zijn, anders wat minder).

if broken it is, fix it you should


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
elgringo schreef op maandag 14 december 2009 @ 10:56:
Als ik het in code oplos moet ik ook n! (met n het aantal records) er door heen. (als het tegen zin en er geen dubbele zijn, anders wat minder).
En waarom heb je het idee dat het in SQL sneller zou kunnen?

Aangezien je niet triviale string vergelijkingen wilt doen, zit er denk weinig anders op dan je complete data-set ophalen, en daar je algoritme op loslaten.

Zeker als het een eenmalig operatie is, moet de run-time IMHO niet zo'n probleem zijn.

Verder kun je dan natuurlijk beter bij het inserten van een nieuw record meteen controleren of er een match met een dubbele is.

Verder is het denk ook belangrijk om eerst een goede definitie te maken van wat je als dubbel beschouwd. Als je daar geen goede definitie van hebt, ga je natuurlijk nooit tot een goede oplossing komen.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
elgringo schreef op maandag 14 december 2009 @ 10:56:
In code ben ik aan het spelen geweest met toupper() en dan vergelijken, regular expressions en endswith. Ik vond dit regelijk traag.
Dat doet allemaal iets anders, wat zijn nu de criteria?
Vooral als ik dezelfde file zoek, dat als ook wat niet lukt met linq, ik betwijfel ook of het uberhaupt mogelijk is, dus \map1\file.mp3 en \mp2\file.mp3. Deze hebben dezelfde filenaam en kan ik dus ook als 'dubbel' zien.
Gaat het alleen om de bestandsnaam? Dan splits je het pad er toch gewoon af (Path.GetFileName)?
Met regex is het traag. waarschijnlijk omdat de bestandsnamen erg lang zijn. (met artiesten en titels is hij een stuk sneller).
Wat voor een regex? Steeds een andere regex is niet zo snel...
Als ik het in code oplos moet ik ook n! (met n het aantal records) er door heen. (als het tegen zin en er geen dubbele zijn, anders wat minder).
Ik denk dat je O(n^2) ipv O(n!) bedoelt. Iets als Soundex kan ook sneller, in O(n).

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 11-09 12:47
Woy schreef op maandag 14 december 2009 @ 11:18:
[...]

En waarom heb je het idee dat het in SQL sneller zou kunnen?
Weet ik niet, puur een hersenspinsel. Ik heb niet al tevel ervaring met SQL en ik vermoed dat hier wat wat optimalisaties in zitten die ik niet in mijn code heb / kan krijgen.
Aangezien je niet triviale string vergelijkingen wilt doen, zit er denk weinig anders op dan je complete data-set ophalen, en daar je algoritme op loslaten.

Zeker als het een eenmalig operatie is, moet de run-time IMHO niet zo'n probleem zijn.

Verder kun je dan natuurlijk beter bij het inserten van een nieuw record meteen controleren of er een match met een dubbele is.
Das het probleem, ik heb nu de databse gemaakt, en niet 10 jaar gelden toen ik begon met mp3 te verzamelen.
Verder is het denk ook belangrijk om eerst een goede definitie te maken van wat je als dubbel beschouwd. Als je daar geen goede definitie van hebt, ga je natuurlijk nooit tot een goede oplossing komen.
Het begrip dubbel wordt door de gebruiker, mij dus, aangeven om records te filteren. Met deze subset kan je vervolgens bestanden (en records verwijderen) na te luisteren of niet. Ik wil het niet automatisch doen.
Dubbel is in principe als alles gelijk is, maar als ik alleen gelijke artiest en titel wil, krijg ik ook de mp3 die op verschillende albums staan.

Ik wil het iig nog via linq to entities op proberen te lossen en snelheids meting doen.
Kan ik een linq statement eigenlijk over meerdere regels declareren?

if broken it is, fix it you should


Acties:
  • 0 Henk 'm!

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 11-09 12:47
pedorus schreef op maandag 14 december 2009 @ 11:19:
[...]

Dat doet allemaal iets anders, wat zijn nu de criteria?
Wat gelijk is? Dat is wat ik als gebruiker ga aangeven. Varierend van compleet hetzelfde, via case insensitieve, tot bevat.
Gaat het alleen om de bestandsnaam? Dan splits je het pad er toch gewoon af (Path.GetFileName)?
Nee, de path is het traagst in regex, dus daarom wilde ik die aanpassen.
Wat voor een regex? Steeds een andere regex is niet zo snel...
Mijn test versie was record uit de met linq gegenereerde dataset halen, en controleren of dezelfde hetzelfde lciht met alles verder dat deze ene. Indien dat meer dan 1 is alles verwijderen uit orginel set en in set zetten die terug gegeven wordt.
Anders alleen deze record verwijderen.

De orginele dataset wordt dus steeds kleiner.
dit is dus n! Ik zoek niet op 1 dubbele, maar op alle dubbele.
Ik denk dat je O(n^2) ipv O(n!) bedoelt. Iets als Soundex kan ook sneller, in O(n).

if broken it is, fix it you should


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
elgringo schreef op maandag 14 december 2009 @ 11:49:
[...]
Weet ik niet, puur een hersenspinsel. Ik heb niet al tevel ervaring met SQL en ik vermoed dat hier wat wat optimalisaties in zitten die ik niet in mijn code heb / kan krijgen.
Een database is snel in het opzoeken van data aan de hand van relationele data. Echter wil jij graag selecteren aan de hand van een niet triviale string operatie. Aangezien je toch alle elementen wilt vergelijken, zul je toch alle elementen op moeten halen.
elgringo schreef op maandag 14 december 2009 @ 11:53:
[...]
Wat gelijk is? Dat is wat ik als gebruiker ga aangeven. Varierend van compleet hetzelfde, via case insensitieve, tot bevat.
Dan is het juist belangrijk dat je goed defineert wanneer dat "Bevat" waar is, want dat is waar je definitie hier niet duidelijk is. Compleet hetzelfde is voor een database redelijk makkelijk ( mits er natuurlijk de juiste indexen zijn ). Voor een case-insensitive zal er waarschijnlijk wel een full table-scan gedaan moeten worden, maar dat is ook nog relatief makkelijk. zelfs het vergelijken van puur de filename zal nog wel kunnen in SQL, maar veel verder moet je denk ik niet willen.
De orginele dataset wordt dus steeds kleiner.
dit is dus n! Ik zoek niet op 1 dubbele, maar op alle dubbele.
Je wilt elk element met elk ander element vergelijken ( Wel of Niet gelijkend ). Dat is in feite n * (n-1) vergelijkingen, echter heb je dan dus ook nog dubbele ( Immers als je 1 met 2 vergeleken hebt is het nutteloos om 2 ook nog eens met 1 te vergelijken ). Om alles te vergelijken krijg je dan 1/2 * n * (n -1)

Ik weet niet hoe groot je data-set is, maar ik zou gewoon in een programma alle elementen ophalen en op alle elementen het verschil bereken ( levenstein distance bijvoorbeeld ). Eventueel kun je dan nog extra criteria toevoegen wanneer elementen gelijk zijn ( Bijvoorbeeld iets met Path.GetFileName )

[ Voor 9% gewijzigd door Woy op 14-12-2009 12:19 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1