15. januar 2006 - 20:56Der er
26 kommentarer og 1 løsning
ObjectDataSource Update
Hejsa derude.
Jeg har rodet med en side hvor jeg har et detailsview der "bliver fodret" af en ObjectDataSource kontrol. Jeg kan bare ikke få det til at virke med opdateringer via ObjectDataSourcen. Så snart jeg har sat "update method" får jeg følgende exception:
No parameterless constructor defined for this object. Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.
Er der nogen der ved hvad der er galt? Jeg er ikke med på hvad det er for en constructor der skulle give problemer?
hvis du slet ikke har nogle constructors på din klasse for du automatisk oprettet en default - så fejlen kommer fordi du selv har angivet andre constructors - der tager parametre. f.eks.
(din object datasource skal kunne tale indholdet af en række i dit grid, og udfra værdierne i den, skal den kunne instantiere en forekomst af den type som er brugt som datagrundlag for rækken). mvh
Ok, men hvordan vil man så typisk gøre hvis man skal bruge et strongly typed dataset som skal bindes til et gridview og man skal kunne lave updates?! Hvilket objekt vil du sende til din select og hvad vil du tage imod i update?
bruger normalt egne typer/collections sammen med objectdatasource, men det du laver skulle meget gerne kunne lade sig gøre uden de store fiksfakserier.
prøv at se om der er noget der springer i øjnene her:
Ok. Jeg var bare vild med ideen med at man kunne autogenerere en klasse til at holde ens data ud fra en sql sætning, som så samtidig er serializable uden man selv skal bakse med den. Men det kan godt være jeg skal holde mig til selv at labe nogen data transfer objekter..
så kan du bare trække tabellen ind i designeren.... så får du en sqldatasource der intert arbejder med datasets, hvilket bevirker at du kan indsætte, slette, opdatere og page uden kode. mvh
Ok, det kan da være jeg lige skal kigge på det. Men tror i sidste ende jeg går tilbage til at lave nogle "dumme" objekter der holder data og så læser jeg ud med en datareader - det er nok det bedste på sigt...
en klar objektmodel i applikationen, hvor man også har lidt mere frihed til at definere sine egne typer (end man har hvis man benytter strongly typed datasets) er jo heller ikke at kimse af ;o)
men ... den deklarative model omkring administration af almindelige stamdata, opsætning eller lignende er klaret på 20 sekunder med en sqldatasource og en wizard..... også noget der er mange der har lidt holdninger til ;o)
ja - det giver normalt det bedste resultat, og der er da en del hjælp at hente med generics i den forbindelse synes jeg.... det med at lave de typestærke lister er jo så en foræring. der er dog så nogle forhold der skal være på plads på de typer du benytter i de lister du databinder til (hvis du vil kunne opdatere og den slags) - sig til hvis du får bøvl med det.... der er nogle småting man lige skal være bekendt med. f.eks. hvilke krav der er til klasserne hvis sortering skal virke og den slags. mvh
ok... det er ikke så kompliceret, men på det lidt "løst i fugerne" (stringbased).
hvis du har et grid med boundfield: <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
så kan du på feltet angive et SortExpression. dette udtryk sørger din datasourcecontrol internt for bliver benyttet som parameter på din selectmetode, hvilket så kræver at du har en sådan metode.
på din objectdatasource kan du have angivet en selectmetode sådan her: SelectMethod="GetAllPersons"
og et SortParameterName SortParameterName="sortExpression"
i dette tilfælde undlader vi selectparametre, så GetAllPersons() er så parameterfri, men da jeg har angivet sortExpressions på feltet og et SortParameterName på objectdatasource giver det, at jeg på den klasse hvor GetAllPersons er implementeret - givet ved TypeName="SampleData.PersonAccess" på objectdatasource
skal have metoden: GetAllPerson(string sortExpression)
som så bliver kaldt i forbindelse med sortering.
i dette tilfælde vil udtrykket kunne have 2 forskellige værdier: "Name" og "Name desc"
så du skal altså selv - i GetAllPersons(string sortExpression) sørger for at finde ud af om det er desc ved at kigge på den parameter du får med.
det er så ikke specielt kompliceret at lave selve sorteringen... det kan du gøre på flere måder, afhængigt af hvad det er for en collection du returnerer.
hvis vi siger at du (og det er en anbefaling) benytter generics, vil GetAllPerson(string sortExpression) så have en signatur som denne:
public List<Person> GetAllPersons(string sortExpression)
og hvis du vil lave en lidt mere generisk løsning af det - kunne du implementere den som noget i denne stil:
public List<Person> GetAllPersons(string sortExpression) { List<Person> persons = SomeDBAccessLayer.GetPersons(); if (sortExpression == String.Empty) { return persons; }
IComparable xcomp = xproperty.GetValue(p1) as IComparable; IComparable ycomp = xproperty.GetValue(p2) as IComparable;
if (orgSortExpression.Contains(" desc")) return ycomp.CompareTo(xcomp); else return xcomp.CompareTo(ycomp);
}); return persons; }
nu er det jo ikke den mest økonomiske implementering (reflection mv), og der er flere måder det kan knække på... men til gengæld kan den sortere hvad som helst, så længe dine sortExpressions matcher dine properties (hvilket jo sådan set også er meget naturligt :o).
... du kan jo evt. udvide med sådan noget som dette her:
... så er alt fnidderfnadderet pakket ind i din comparer istedet.
nu er ovenstående så specifikt på sammenligning af instanser af Person, men du kan relativt let skrive det om til en generisk sorteringscomparer, som så kan sortere hvad som helst:
public class Sorter<T> : Comparer<T> { private string _sortExpression = String.Empty;
Ok, så er jeg med. Jeg regner med at prøve at implementere det inden alt for længe, men det er til et fritidsprojekt så det er lidt an på tiden. Endnu engang tak for hjælpen...
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.