I dette særtema ser vi på, hvordan cloud og AI bliver fundamentet for virksomhedernes digitale forretning, og hvordan de nye muligheder for automatisering og forretningsværdi kan udnyttes uden at miste overblik, sikkerhed og menneskelig kontrol.
Det er ret normalt på compile time at generere klasser udfra tabeller eller tabeller udfra klasser.
Det kan de såkaldte O/R mappere gøre.
Det er lidt usædvaneligt at ville gøre det runtime.
Hvorfor kan du ikke bare slå op med navn i en eller anden collection ? Du kan jo alligevel ikke bruge de dynamisk genererede properties i din kode, da de ikke er kendte på compile time.
Hvis du virkeligt vil gøre det, så skal vi over i noget dynamisk kode generering.
Jeg kan godt lave et eksempel, men overvej lige om det faktisk er noget du har brug for.
using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Text; using System.Reflection; using System.CodeDom.Compiler;
using Microsoft.CSharp;
namespace E { public class Data { public virtual string Name { get { return "<incomplete>"; } } } public static class OR { private const string nstemp = @"using System; using E; namespace ORGen {{ {0} }}"; private const string clztemp = @"public class {0} : {1} {{ {2} }}"; private const string fldtemp = @"private {0} {1};"; private const string proptemp = @"public {0} {1} {{ get {{ return {2}; }} set {{ {2} = value; }} }}"; private const string namtemp = @"public string Name {{ get {{ return ""{0}""; }} }}"; public static Type Extend(Type baseclz, IDbConnection con, string tblnam) { StringBuilder sb = new StringBuilder(); IDbCommand cmd = con.CreateCommand(); cmd.CommandText = "SELECT COLUMN_NAME,DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='" + tblnam + "'"; IDataReader rdr = cmd.ExecuteReader(); while(rdr.Read()) { string colnam = (string)rdr[0]; colnam = colnam.ToLower(); string propnam = colnam.ToUpper()[0] + colnam.Substring(1); string coltyp = (string)rdr[1]; if(coltyp == "int") { // OK } else if(coltyp == "varchar") { coltyp = "string"; } else { throw new Exception(coltyp + " not supported"); } sb.Append(String.Format(fldtemp, coltyp, colnam)); sb.Append(String.Format(proptemp, coltyp, propnam, colnam, colnam)); } rdr.Close(); sb.Append(String.Format(namtemp, tblnam)); string src = String.Format(nstemp, String.Format(clztemp, tblnam, baseclz.FullName, sb.ToString())); CodeDomProvider comp = new CSharpCodeProvider(); CompilerParameters param = new CompilerParameters(); param.GenerateInMemory = true; param.ReferencedAssemblies.Add("System.dll"); param.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location); CompilerResults res = comp.CompileAssemblyFromSource(param, src); Assembly asm = res.CompiledAssembly; return asm.GetType("ORGen." + tblnam); } } public static class ORUtil { private static IDbConnection con; private static Dictionary<string,Type> cache = new Dictionary<string,Type>(); public static IDbConnection Con { set { con = value; } } public static Type Extend(string tblnam) { if(!cache.ContainsKey(tblnam)) { cache.Add(tblnam, OR.Extend(typeof(Data), con, tblnam)); } return cache[tblnam]; } public static Data Read(IDataReader rdr, string tblnam) { Data res = (Data)Extend(tblnam).GetConstructor(new Type[0]).Invoke(new object[0]); for(int i = 0; i < rdr.FieldCount; i++) { if(!rdr.IsDBNull(i)) { res.GetType().GetProperty(rdr.GetName(i)).SetValue(res, rdr.GetValue(i), null); } } return res; } public static IList<Data> ReadAll(IDataReader rdr, string tblnam) { IList<Data> res = new List<Data>(); while(rdr.Read()) { res.Add(Read(rdr, tblnam)); } rdr.Close(); return res; } public static IList<Data> ReadAll(string tblnam) { IDbCommand cmd = con.CreateCommand(); cmd.CommandText = "SELECT * FROM " + tblnam; IDataReader rdr = cmd.ExecuteReader(); return ReadAll(rdr, tblnam); } } public class Program { public static void Main(string[] args) { Data o = new Data(); foreach(PropertyInfo pi in o.GetType().GetProperties()) { Console.WriteLine(pi.Name + " = " + pi.GetValue(o, null)); } SqlConnection con = new SqlConnection("server=ARNEPC3\\SQLEXPRESS;Integrated Security=SSPI;database=Test"); con.Open(); ORUtil.Con = con; Type x = ORUtil.Extend("T1"); Data ox = (Data)x.GetConstructor(new Type[0]).Invoke(new object[0]); foreach(PropertyInfo pi in ox.GetType().GetProperties()) { Console.WriteLine(pi.Name + " = " + pi.GetValue(ox, null)); } IList<Data> lst = ORUtil.ReadAll("T1"); foreach(Data d in lst) { foreach(PropertyInfo pi in d.GetType().GetProperties()) { Console.WriteLine(pi.Name + " = " + pi.GetValue(d, null)); } } con.Close(); Console.ReadKey(); } } }
Sært - jeg troede faktisk at jeg havde postet den.
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.