Avatar billede Keagir Nybegynder
02. april 2010 - 23:49 Der er 27 kommentarer og
1 løsning

LINQ, hent et match fra et array,

Meget simpelt. Jeg har noget kode, der virker uden brug af LINQ. Jeg vil gerne skrive det om til LINQ, men jeg får en 'InvalidOperationException'.
Nedenunder er der et eksempel på det der kører, og efter kommer mit LINQ version af samme kode block.



PropertyInfo[] properties = o.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var property in properties) {
      for (int i = 0; i < reader.FieldCount; i++) {
        if (reader.GetName(i).Equals(property.Name, StringComparison.CurrentCultureIgnoreCase) && reader.GetValue(i).GetType().ToString() != "System.DBNull") {
                            property.SetValue(o, reader.GetValue(i), null);
                            break;
                        }
                    }
                }

------------------------ Min LINQ ver --------------------------
PropertyInfo[] properties = o.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
  for (int i = 0; i < reader.FieldCount; i++) {
                    var property = properties.Single(p => (p.Name.Equals(reader.GetName(i), StringComparison.CurrentCultureIgnoreCase)) && (reader.GetValue(i).GetType().ToString() != "System.DBNull"));
                    property.SetValue(o, reader.GetValue(i), null);
                    properties = properties.Where(val => val != property).ToArray();
                }

----------------------------------------------------------------
Som man kan se, så fjerner jeg den property fra properties collection, som jeg umiddelbart har brugt.

Er der nogen, der kan gennemskue hvad jeg mangler eller gør forkert i mit LINQ udtryk?
Avatar billede Syska Mester
03. april 2010 - 00:02 #1
http://msdn.microsoft.com/en-us/library/bb156472(VS.96).aspx

Single smider den exception ... se linket. Hvis perperties indeholder mere end et element eller skal ik' nogen.

Sagt på en anden måde, Single skal returnere et element
Avatar billede Syska Mester
03. april 2010 - 00:02 #2
Returns the only element of a sequence, and throws an exception if there is not exactly one element in the sequence.

InvalidOperationException - source has more than one element.
Avatar billede Keagir Nybegynder
03. april 2010 - 00:05 #3
Hmmm ok, men den burde kun finde et match i min properties collection. Derfor tømmer jeg den også umiddelbart under andet gennemløb. Jeg har mistænkt Single() for at være problemet. Men min collection indholder kun et match :S
Avatar billede Keagir Nybegynder
03. april 2010 - 00:10 #4
Det kan være jeg har misforstået Single(). Tænkte det bare betød at jeg forventer at få en tilbage....
Jeg har desuden prøvet at erstatte Single() med en Where() og sidst i mit Ling udtryk sætte et First() på....men det hjalp heller ikke... sagen er at jeg sådan set bare skal have det match ud som jeg spørger på ved at sammenligne p.Name med mit reader objekts kollonne navn.
Avatar billede Syska Mester
03. april 2010 - 00:38 #5
Du overskriver også din properties hver gang ... er det meningen?

Jeg kan ikke lige helt gennemskue hvad du prøver på, men virker lidt som noget mssql match på objecter ... hvis? Har du så overvejet en OR mapper ?

mvh
Avatar billede Keagir Nybegynder
03. april 2010 - 00:45 #6
Ja, jeg overskriver min properties collection, hvor jeg fjerner det enkelte item, som jeg har fået matchet.

Jeg har ikke brug for en OR mapper, jeg forsøger blot at få tæmmet noget Linq. Det virker også fint, indtil jeg til lige forsøgte det her.

Første gennemløb kører helt uden problemer, det er andet gennemløb, hvor det virker som om reader objektet ikke kan sammenlignes med. Den løber ihvertfal alle mine p.Name igennem, uden at ramme noget, og falder så ud med en InvalidOperationException, da den sikkert ikke finder noget.

Det burde vel kunne køre flere gennemløb igennem min løkke og finde et match...
Avatar billede Keagir Nybegynder
03. april 2010 - 00:54 #7
Damn...
Kan se at den forsøger at matche med noget der ikke findes. Der må findes en måde man kan angive: Enten finder du noget og returnerer det, eller gør intet....finder lige ud af det...
Avatar billede Keagir Nybegynder
03. april 2010 - 00:59 #8
Fik det fixet. Jeg bruger en FirstOrDefault() istedet for en Single(). Herefter spørger jeg på om min property er forskellig fra null, og mapper herefter...lærte lige noget nyt...tildeler mig selv point :D
Avatar billede Keagir Nybegynder
03. april 2010 - 00:59 #9
Tak for tiden...
Avatar billede Syska Mester
03. april 2010 - 01:04 #10
Øhhh, hvordan kan du selv tage point for at jeg kommer med løsningen ...

Du spurgte om hvorfor du fik en exception, og det gjorde du pga Single som du også selv skrev til sidst.

mvh
Avatar billede Syska Mester
03. april 2010 - 01:05 #11
ikke løsnigen men svaret vel og mærket.

"Er der nogen, der kan gennemskue hvad jeg mangler eller gør forkert i mit LINQ udtryk?"
Avatar billede Keagir Nybegynder
03. april 2010 - 01:25 #12
Jeg vidste godt jeg fik en exception, den kom ligsom frem under min debug session. Jeg har en catch block, der fangede den. Du kom ikke med nogen løsning, men fortalte mig noget, jeg allerede havde en fornemmelse for. Jeg fandt selv fejlen, som jeg skrev og kunne se, at jeg havde overset noget, da jeg begyndte at tjekke mine variabler igennem en for en. Jeg fik ligsom heller ikke nogen alternativ løsning på det jeg forsøgte at opnå. Jeg gik på et Linq site, læste muligheder for hvad jeg skulle bruge, fandt hvad jeg havde brug for....

Synes det er lidt plat at du skriver tilbage på den måde, når jeg endda takker dig for din tid...havde jeg selv synes du skulle have nogle point, ville jeg ikke være blank for at gøre det...
Avatar billede janus_007 Nybegynder
03. april 2010 - 01:29 #13
Keagir -> Nu giver jeg buzzz ret vedr. de point :) Men udover det så virker det som om du blander lidt oldschool sammen med Linq. Jeg ville lave en extension og så selecte udfra den, se her:

Din main:

var reader = new DataTableReader(new DataTable());
            object o = new object();

            var properties = o.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).OfType<PropertyInfo>();
           

            var propertyInfos = properties.Where(x => reader.GetNames().Contains(x.Name));

            for (int i = 0; i < propertyInfos.Count(); i++)
            {
                propertyInfos.ElementAt(i).SetValue(o, reader.GetValue(i), null);
            }


og så en extension:

public static class Extensions
    {
        public static IEnumerable<string> GetNames(this DataTableReader reader)
        {
            for (int i = 0; i < reader.FieldCount; i++)
            {
                if(reader.GetValue(i).GetType().ToString() != "System.DBNull")
                    yield return reader.GetName(i);
            }
        }
    }


På den måde bruger du Linq til fulde, men om det er smart lige i din sammenhæng er svært at sige. Specielt uden du slet intet har forklaret om hvad det er du vil opnå (udover det åbenlyse at smide nogle værdier ind i dit object)

Anyway.. håber du lærte noget mere om Linq :)
Avatar billede Keagir Nybegynder
03. april 2010 - 01:36 #14
-> Janus tak for svar, som jeg har skrevet lidt tidligere, så er jeg selv næsten lige gået igang med at komme under huden på Linq, men hvis jeg skulle give point for det jeg fik, ville det være et sted mellem 2-5 point, og det ville nok være lidt pinligt at dele ud.

Jeg kan paste hele min metode ind her:
Som skrevet før, er det blot noget hyggekode, jeg har skrevet og eksperimenteret med. Jeg er sikker på, man altid kan optimere eller skrive noget smartere

private T MapFields<T>(T o, IDataReader reader) where T : class {
            try {
                PropertyInfo[] properties = o.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
                for (int i = 0; i < reader.FieldCount; i++) {
                    var property = properties.FirstOrDefault(p => (p.Name.Equals(reader.GetName(i), StringComparison.CurrentCultureIgnoreCase)) && (reader.GetValue(i).GetType().ToString() != "System.DBNull"));
                    if (property != null) {
                        property.SetValue(o, reader.GetValue(i), null);
                        properties = properties.Where(val => val != property).ToArray();
                    }
                }
            } catch (InvalidOperationException ex) {
                var log = new LogManager();
                log.Error("Attempt to match a entity property with a reader field column failed.", ex);
            } catch (Exception ex) {
                var log = new LogManager();
                log.Critical("An unknown error occured when mapping fields from entity with reader object columns", ex);
            }
            return (!(o is T)) ? default(T) : o as T;
        }
Avatar billede Keagir Nybegynder
03. april 2010 - 01:38 #15
Som man kan se bruger jeg reflection, generics og linq....

og yes, fixede selv problemet og lærte noget nyt omkring linq :D
Avatar billede Syska Mester
03. april 2010 - 01:41 #16
Spørgsmål:
Er der nogen, der kan gennemskue hvad jeg mangler eller gør forkert i mit LINQ udtryk?

Svar:
Hvad du netop gjorde forkert var at bruger Single og at du netop ville få den Exception hvis Single returnere andet end 1 resultat.

Løsningen ud fra den synes jeg er ret åbenlys ... men ville gerne vide hvad du sag og roede med for at komme med den bedste løsning, og ikke bare skud i tågen ...

Så jeg kan ikke se hvad jeg ikke har svaret på ...
Avatar billede Keagir Nybegynder
03. april 2010 - 01:49 #17
Du kan ikke bare tage en enkelt sætning ud uden at tage hele mit setup med i betragting GOSH, for dælen hvor er du irriterende. Hvis du selv mener, at jeg burde give dig fuld point for noget, jeg allerede sad og læste mig frem til på -> http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx

Når jeg sætter 65 point op, så betyder det at jeg gerne vil se noget kode forslag, som Janus har copy-pasted ind fx. Hvis du mener at dit svar giver ret til fuld point, uden at give mig et forslag så er det en smule overrated. Desuden er jeg slet ikke ny her, så jeg ved hvordan det fungerer. Min oprindelige bruger er fra 2001, men pga. dårlig migrering fra nogle brugerdatabaser, blev jeg efter lang tid nødsaget til at lave en ny profil herinde. Så jeg ved godt, hvordan det fungerer herinde med at give point...at copy-paste sites ind her, som jeg selv kan google mig frem til, er simpelthen ikke nok. Som sagt før, jeg opdagede, hvad der gik galt.
Avatar billede Keagir Nybegynder
03. april 2010 - 01:54 #18
Jeg tror, ikke du har læst min kode uden Linq udtrykket...det kunne være jeg skulle ha' forklaret det med ord istedet for at kopiere det kode ind. Mit forsøg på var at skrive noget kode med linq, så jeg kunne opnå det samme som det uden, og gerne med kodeeksempel som forslag. No more no less...
Avatar billede Keagir Nybegynder
03. april 2010 - 02:11 #19
Fordi jeg selv løste mit problem... og selv opsøgte løsningen... venligst undgå at kommentere eller svare på mine kode spørgsmål i fremtiden. Jeg synes du er irriterende, og opfører dig som en mobset teenager. Meget umoden og overfladisk. Som skrevet i mit spørgsmål som du bliver ved med at referere, skriver jeg også "hvad jeg MANGLER"...=> et forslag til noget der kunne fikse...

Folk er herinde for at hjælpe, som jeg også ville gøre uden at tage points som det afgørende...jeg gider ikke at bruge mere tid på en teenager dreng...smut i seng...det er ved at være sengetid...og jeg fik lige ødelagt min fucking weekend på noget nyttløst snik snak....
Avatar billede Syska Mester
03. april 2010 - 02:01 #20
Jeg synes ikke rigtig dine argumenter holder vand, du fik 100% svar på hvad du spurgte om ...

Hvis vi skal tage hele dit setup med ... burde du så ikke også have postet oplysninger om det? Altså ... hvad du sender med ... hvor din reader kommer fra ...

Vi kan jo ikke have nogen ide om hvad der var i din reader eller din properties klasse ... så kan ikke selv teste det.

Exception passede 100% på at din Single metode fejlede, og at din debugging ikke har været grunding nok ...

Det var nu kun 60 point og ikke de 65 som du siger. De point siger jo kun noget om hvor meget du selv synes dit spørgsmål er værd ... og her synes du det var 60 værd. Jeg ser ingen steder hvor du sprøger om kode, men efterlyser din LINQ fejl.

Som sagt før, så var det mig der opdagede hvad der var galt ... netop Single. Når jeg ikke har alt din kode, så er det umuligt for mig at teste med de setup betingelser du har ...

Men du må da beholde de point ... jeg ville da bare gerne vide hvorfor du selv tog dem, efter du havde fået svaret.
Avatar billede Syska Mester
03. april 2010 - 02:03 #21
Jeg synes ikke rigtig dine argumenter holder vand, du fik 100% svar på hvad du spurgte om ...

Hvis vi skal tage hele dit setup med ... burde du så ikke også have postet oplysninger om det? Altså ... hvad du sender med ... hvor din reader kommer fra ...

Vi kan jo ikke have nogen ide om hvad der var i din reader eller din properties klasse ... så kan ikke selv teste det.

Exception passede 100% på at din Single metode fejlede, og at din debugging ikke har været grunding nok ...

Det var nu kun 60 point og ikke de 65 som du siger. De point siger jo kun noget om hvor meget du selv synes dit spørgsmål er værd ... og her synes du det var 60 værd. Jeg ser ingen steder hvor du sprøger om kode, men efterlyser din LINQ fejl.

Som sagt før, så var det mig der opdagede hvad der var galt ... netop Single. Når jeg ikke har alt din kode, så er det umuligt for mig at teste med de setup betingelser du har ...

Men du må da beholde de point hvis du vil ... jeg ville da bare gerne vide hvorfor du selv tog dem, efter du havde fået svaret.
Avatar billede Syska Mester
03. april 2010 - 02:05 #22
Arghh, eksperten fucker mig ... :-(

Jo, har læst din kode igennem, men kunne stadig kun se det ene spørgsmål.

Jeg fortalte bare hvad der gik galt ... og uden de andre ting er det jo ik' sikkert min test kode vil give samme fejl uden ens setup :-)

mvh
Avatar billede Keagir Nybegynder
03. april 2010 - 02:14 #23
JEg gider ikke at bruge tid i denne tråd mere....venligst find nogle andre...jeg skal forsøge at være meget explicit i mine formuleringer fremover, så man undgår at tro, man har givet et kvalificeret svar og løsningsforslag...
Avatar billede Keagir Nybegynder
03. april 2010 - 02:18 #24
Jeg er glad for adminstratoren gik ind her...tusinde tak :)
Så behøver jeg ikke blive irriteret over meningsløse indlæg mere :)

Et oprigtigt tak og god weekend til Jer alle :)
Avatar billede Syska Mester
03. april 2010 - 02:27 #25
Jeg kan jo ikke læse mellem linjerne ...

Jeg vil ikke kommentere overstående personlige angreb på mig, men synes det er relevant at høre hvorfor folk tager point for spørgsmål hvor der er kommet svar.

Ingen har nogen sinde sagt det skulle være fuld point, 50%, 10% ... det er dine antagelser.

Administratoren ... hvad, hvad og hvor?

Lige over og god weekend ... husk, man kan godt diskutere ting, 2 personer, 2 meninger.

// over and out
Avatar billede Keagir Nybegynder
03. april 2010 - 02:41 #26
Det med single havde min kollega på min msn messenger fortalt mig, og jeg pastede mit forslag og problem ind her, for at få nogle alternative forslag....så dit svar desværre ikke nogle point værd, og ærligt talt, synes jeg mest at det har været irriterende, at have dig i min tråd...så for sidste gang, beder jeg dig på en pæn måde igen.

Undgå venligst at kommentere eller komme med forslag til mine fremtidige tråde. Jeg har ikke nok spildtid i min hverdag.
Avatar billede Syska Mester
03. april 2010 - 02:55 #27
Men derfor sagde jeg stadig:
Din Single returnere ikke kun 1 element  ... derfor den Exception. Da du så kørte igennem din debug ... viste det sig også at du fik resultater som du ikke regnede med.

Jeg kan ikke forstå hvorfor du er så sur og irriteret. Jeg svarede ... du tog point, og jeg sprugte hvorfor ... længere er den ik'. Jeg har på intet tidspunkt sagt at jeg ville have de point, men kunne bare ikke forstå det. Du har så forklaret hvad du mente er op og ned. Jeg har argumenteret for mit syn på det. End og story.

Så vidt jeg ved, kan du kun bede mig om at lade være med at skrive her ... hvis der et sted i deres betingelser står at du kan nægte mig adgang, så må du gerne henvise mig dertil.
Avatar billede Keagir Nybegynder
03. april 2010 - 03:01 #28
Jeg lukker min fucking profil herinde nu...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester