Yes, ORM uses TableDirect whenever possible. Fundamentally you should be seeing the same behavior as with yoru direct SqlCeResultSet. Can you post a little bt of the code you're using for both the entity definition and the insert?

This is challenging, to say the least. The “slowness” appears to be in the fact that I have to iterate the fields of the target object instance and fill them. Just the iteration itself (as
opposed to the call to set the property) appears to be taking the largest percentage of the time. I did find some other places to do some caching and optimizations, so I’ve improved things by roughly 20% in the ORM case, but it’s still nowhere
near the statically-bound speed. I’ll keep digging, but I’m not certain we’ll be able to squeeze much more out of it simply because the code has to handle object types that are unknown at compile time.

So using your DB, with 100k records the non-ORM select takes me about 500ms. With the original ORM code (what you’re using) it took rough 5200ms. The new code trims that down to around 4000ms.
This code is checked in as a change set (though not yet as a release). Let me know if it at least improves things on your end.

This is challenging, to say the least. The “slowness” appears to be in the fact that I have to iterate the fields of the target object instance and fill them. Just the iteration itself (as opposed to the
call to set the property) appears to be taking the largest percentage of the time. I did find some other places to do some caching and optimizations, so I’ve improved things by roughly 20% in the ORM case, but it’s still nowhere near the statically-bound speed.
I’ll keep digging, but I’m not certain we’ll be able to squeeze much more out of it simply because the code has to handle object types that are unknown at compile time.

So using your DB, with 100k records the non-ORM select takes me about 500ms. With the original ORM code (what you’re using) it took rough 5200ms. The new code trims that down to around 4000ms. This code
is checked in as a change set (though not yet as a release). Let me know if it at least improves things on your end.

One possibility to speed it up is to move some of the work into a constructor for the entity definition. Assuming one uses the EntityGenerator, that no extra work on the part of the user.

I just tested it quickly and the same 2M rows now loads in 17,500ms! There's probably a bit more speed to had from my little test. I've set up so the constructor takes the field collection and the result. It casts and sets the property
value based on the field name.

The big change would be modifying the EntityGenerator to generate the constructor. (I just wrote the constructor by hand for my test.)

So I took your idea and ran with it. I've got a preliminary (meaning it's not been tested against a lot of types or null fields, etc) but it trims the time for my earlier test to about 1400ms, which is something like a 75% improvement.

Once I've tested it further, I'll update the EntityGenerator but for now you have to manually add a method into your entity class. Here's an example (it's the one for your test class):

Sorry for the delay, I'll zip and send. But looking at the code, that's the idea.

I started to set it up such that it would fall back to the "normal" way (PropertyInfo.SetValue) method, if a constructor with parameters for the entity wasn't found. But the caching was getting me a little mess up and I had to move on. That would
allow backwards compatibility with previously generated entity definitions.

Here's a part of the code I had... But the caching of the constructor messes it up: if the entity doesn't have a parameterized constructor the GetConstructorForType return the non-parameterized one - which blows up on the invoke. Either
we need 2 caches... try the param cache first, then the non-param one. Or we need to be able to identify if the constructorInfo object is parameterized or not and invoke it properly.

Mine was similar, though I moved stuff out to another method. I also didn't use a constructor, but opted for a private static method so as to not pollute either the constructor or the exposed object model (helping prevent developers from doing things
they shouldn't). Take a look at the changes I checked in and see if it does what you're after.

The desktop could probably benefit even further by emitting typesafe property setters, but the issue here is that I'm trying to keep the code base CF-compatible. I could conditionally deal with Emit as well as PLINQ, but it adds complexity which I
don't have a lot of time for testing. If you want to try it and submit a patch, I'm all for seeing what it gives us.