We have a class library that does some basic operations similar to an ORM, basically we can do something like this:
conn.Query<EntityType>("select * from table");
and get back a List<EntityType>
. Since the mapping from column names to properties on the entity type is stored inside the entity type, we can easily construct basic objects when we need to with only a subset of the properties.
The problem is, this code relies heavily on reflection, and we just discovered that the overhead, which we knew we had, was far bigger than what we anticipated.
example timings of various operations related to a "select * from table":
- IDataReader, loop through all the rows, 178ms
- IDataReader, call GetValues to get the object[] array, for all rows, 260ms
- IDataReader, call GetValues, construct new object and add to list, for all rows, 356ms
- IDataReader, call GetValues, construct new object, use reflection to copy values to properties, ~10.500ms (29x step 3.)
We cache the reflection involved, but still there's too much overhead.
Since 99% of the objects involved are simple properties with (1 or 2 backing fields), I thought I could just generate the following code through IL/DynamicMethod:
instance._Id = (int)value;
This fails with FieldAccessException
, and I assume this is because the fields are private. Is there any way for me to generate this code at all, or am I just barking up the wrong tree security-wise?
Yes; in your
DynamicMethod
you need to tell it to associate itself withEntityType
; then the access problem goes away. Use the overload that setsowner
totypeof(EntityType)
, andskipVisibility
totrue
.However, in most cases you should be able to go the the properties virtually as quickly as the fields. So prefer the properties unless there is a good reason to choose fields. Of course, if using attributes you can let the user decide, by decorating the most appropriate.