02. april 2010 - 23:49Der 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?
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
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.
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...
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...
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
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...
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)
-> 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; }
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å ...
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.
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...
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....
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.
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.
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...
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.
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.
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.
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.