10. maj 2019 - 18:21Der er
18 kommentarer og 1 løsning
Extended Class i C#
Hej, Jeg sidder med et problem med omskrivning af noget PHP kode til C#. Jeg har fået forklaret af en ven, at man i PHP kan extende en klasse som så arver alle metoder fra denne klasse. I koden er der mange forskellige objekter som alle har en insert, update og en delete metode. De 3 metoder vil vi gerne have samlet i en klasse, som så står for SQL kald for alle typer objekter. Men eftersom database klassen ikke kender objekterne og hvor mange variabler hver enkelt objekt har, så skulle man kunne extende database klassen, som derved så får kendskab til det enkelte object. Jeg ved ikke helt om det kan lade sig gøre, og i så fald, er det god programmeringskik at gøre. Det vil være nemmere, kun at have en klasse, men problemet er at database klasse ikke kender det objekt man prøver at gemme. Giver det mening det jeg skriver? På forhånd tak
Og man kan godt finde alle properties dynamisk i C#.
Men men men.
Jeg ville ikke putte data og funktionaliteten til at gemme data i samme klasse.
Og der er masser af ORM frameworks til .NET hvor man slet ikke skal skrive database tilgangskoden selv. Man giver bare sin data klasse til et ORM framework der saa goer det der skal goeres.
Jeg synes ikke det er så nemt at læse/forstå. Og jeg ved ikke om det er den vej jeg skal gå. Jeg er faktisk lidt i tvivl om jeg hellere vil have det på den gamle måde. Der er godt nok lidt mere vedligehold, men jeg synes det er nemmere at overskue. Jeg tænkte bare at der var en lille hurtig løsning. Det er sikkert nemt, når først det er sat op. Men jeg er ikke sikker på at jeg nogensinde FÅR det sat op. Og hvad hvis man ikke vil opdatere alt fra sit object, vil man så ikke overskrive de felter i DB med tomt data?
Jeg tror det bliver for omstændigt. Jeg kom jo til at tænke på at de forskellige objecter indeholder mere end det der skal opdateres. Tror det bliver for besværligt at holde styr på, i stedet for at lave de funktioner til insert og update på den helt gamle facon :-) Det bliver sådan indtil videre. Men hvordan skulle man i så fald lave en klasse der itererer over et object, når det helst skulle være en klasse som alle objecter kan gemmes/opdaters fra? Meningen var jo at uanset hvilket object man ville gemme/opdatere, skulle det være samme funktion som stod for den. Man skal selvfølgelig bygges sin SQL op, men hvordan får jeg gået alle properties igennem, når jeg ikke ved hvilket object der skal gemmes. Jeg er jo vant til at man f.eks sender et kunder object med som parameter når man kalder funktionen til databasekaldet.
namespace E { public abstract class Saver { private static string Q(object v) { return (v is string) ? ("'" + v + "'") : v.ToString(); } public void Save() { string clznam = this.GetType().Name; string flist = string.Join(",", this.GetType().GetProperties().Select(pi => pi.Name)); string vlist = string.Join(",", this.GetType().GetProperties().Select(pi => pi.GetValue(this, null)).Select(v => Q(v))); string sql = string.Format("INSERT INTO {0}({1}) VALUES({2});", clznam, flist, vlist); Console.WriteLine(sql); } } public class X : Saver { public int A { get; set; } public string B { get; set; } } public class Program { public static void Main(string[] args) { X o = new X { A = 123, B = "ABC" }; o.Save(); Console.ReadKey(); } } }
namespace E { public class IgnoreAttribute : Attribute { } public abstract class SmartSaver { private static string Q(object v) { return (v is string) ? ("'" + v + "'") : v.ToString(); } public void Save() { string clznam = this.GetType().Name; string flist = string.Join(",", this.GetType().GetProperties().Where(pi => pi.GetCustomAttributes(typeof(IgnoreAttribute), true).Length == 0).Select(pi => pi.Name)); string vlist = string.Join(",", this.GetType().GetProperties().Where(pi => pi.GetCustomAttributes(typeof(IgnoreAttribute), true).Length == 0).Select(pi => pi.GetValue(this, null)).Select(v => Q(v))); string sql = string.Format("INSERT INTO {0}({1}) VALUES({2});", clznam, flist, vlist); Console.WriteLine(sql); } } public class X : SmartSaver { public int A { get; set; } public string B { get; set; } [Ignore] public string C { get; set; } } public class Program { public static void Main(string[] args) { X o = new X { A = 123, B = "ABC", C = "nothing" }; o.Save(); Console.ReadKey(); } } }
Tak for koden :-) Beklager det sene svar. Det ser rigtig fint ud. Tror måske jeg vil give det et forsøg. Men er det rigtigt forstået, at når jeg f.eks har et object, som jeg gerne vil gemme, så er jeg nødt til at gemme alle data i objectets properties? Eller er det det kode du har lavet til at ignorere?
Det er et stykke tid siden jeg har brugt eksperten. Er man holdt op med at give points?
Har så lige et andet problem. Jeg får en fejl med denne Select(pi => pi.Name) 'PropertyInfo[]' does not contain a definition for 'Select' and no accessible extension method 'Select' accepting a first argument of type 'PropertyInfo[]' could be found (are you missing a using directive or an assembly reference?)
Jeg har prøvet at tilføje en reference til system.data.linq. Men det hjælper ikke.
Jeg har ikke en system.linq. Den finder jeg i system.data.linq. Så har jeg læst at man skal have system.core. Men den kan jeg ikke få lov til at lave en reference til.
Jeps :-) Men når jeg skriver det, får jeg følgende fejl: The type or namespace name 'Linq' does not exist in the namespace 'System' (are you missing an assembly reference?)
Det er et website. Men når jeg åbner websites property page, kan jeg under referencer kun se, dem jeg allerede har importeret. Der er hverken system.core eller system.linq. Der er en system.data.linq, men den duer jo så ikke. Jeg har også lige hentet den nyeste version (2019) af Visual Studio. Jeg kan altså ikke se det nogen steder. Men når jeg går ind og tilføjer en reference og her vælger system.core, får jeg at vide at der allerede er en reference til system.core. Det er da lidt underligt. Hvor kan jeg se det? De andre referencer som jeg kan se i web.config filen, dem kan jeg godt se er valgt.
Hej igen, Lige en hurtig kommentar til dette problem. Det viser sig, at når koden ligger i en class fil i mappen app_code, så kan man ikke bruge using system.linq. Men så snart man flytter den ud i roden, forsvinder fejlen. Lidt underlig fejl. Men det fik mig da sporet lidt ind på en anden løsning. Den er måske ikke helt så elegant som din, men dog noget der virker :-)
Synes godt om
Ny brugerNybegynder
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.