generics - C# and Reflection don't work twice in a row -
i've problem , can't figured out how solve it.
i've class fetching data database, in class i've method simple select * method called
list<t> all<t>(string tablename)
and have specify resource want fetch, example
all<user>("users")
and, aside classic sql reader , sql command, core of method this
public override list<t> all<t>(string resource) { list<t> result = new list<t>(); using (mysqlconnection sqlconnection = new mysqlconnection(connectionstring)) { sqlconnection.open(); try { string query = "select * " + resource + " 1=1"; using (mysqlcommand sqlcommand = new mysqlcommand(query, sqlconnection)) { lock (locker) { mysqldatareader reader = sqlcommand.executereader(); if (reader.hasrows) { while (reader.read()) { t model = activator.createinstance<t>(); dictionary<string, object> _properties = new dictionary<string, object>(); (int = 0; < reader.fieldcount; i++) { string property = reader.getname(i); object value = reader.getvalue(i); _properties.add(property, value); } var type = model.gettype(); var method = type.getmethod("setproperties"); var invoked = method.invoke(model, new object[] { _properties }); result.add(model); } } reader.close(); } } } catch (exception ex) { program.eventlogger.add(new event(eventtype.error, "sql data providers", "exception catched on all", ex)); } { sqlconnection.close(); } } return result; }
basically, based on type method header, method try create new instance of specific type, later each field query, fills attributes of class on temporaneous list. once it's done try call method "setproperties" set every attributes of class using reflection.
this core of setproperties, equal each entity:
public virtual bool setproperties(dictionary<string,object> properties) { if(this.validatedata(properties)) { fillnullableattributes(properties); // iterate trough every key : value pairs in properties foreach (keyvaluepair<string, object> kvp in properties) { if (this.data.contains(kvp.key)) { var property = this.gettype().getproperty(kvp.key); propertyinfo propertyinfo = this.gettype().getproperty(kvp.key); // set current fetched key given value if !null if (kvp.value != null) { type fetchedtype = nullable.getunderlyingtype(property.propertytype) ?? property.propertytype; object safeconversion = (kvp.value == null || kvp.value == dbnull.value) ? null : convert.changetype(kvp.value, fetchedtype); if (propertyinfo.canwrite) { propertyinfo.setvalue(this, safeconversion, null); } } } } return true; } return false; }
in conclusion result, list, returned , specific entity have own bindinglist filled. binding list, each entity described follow:
public static bindinglist<seller> items = new bindinglist<seller>();
this code works fine, if there's lot of space improvements know, if called twice this:
user.items = new bindinglist<user>(provider.all<user>("users")); user.items = new bindinglist<user>(provider.all<user>("users"));
the second list filled empty entities, counting of correct empties... , shouldn't occurs.
the thing figured out, debugging, on second call
var invoked = method.invoke(model, new object[] { _properties });
invoked set false.
the result of:
var invoked = method.invoke(model, new object[] { _properties });
is return value setproperties
method, not whether method invoked question indicates. setproperties
method telling unable work, debug , find answer.
Comments
Post a Comment