Marcus wrote:
Sounds good, have you published the feature list or is it a secret
For customers it's a secret still because we'll cut features if time's short. So posting a list will give long faces if there's no time left.
They mainly centered on the only area which I think has some room for improvement which is "Reading Data". LLBLGen does a great job for Insert / Update and Delete but performance for Read could improved. Eg. Caches for immutable data (immutable data could be marked as such in the designer).
Data reading is improved a lot, by removal of the 2 bottlenecks inside the entity creation code (name-to-index for fields creation and defaultvalue creation) plus all fields now share static info which means a much much lower memory footprint (>60%)
Caching of data is and will always be up to the developer, as caching data has to be done high up the application stack, not deep down in the DAL.
PrefetchPath is GREAT, but only works with heavy Entities which don't have lightweight read only versions (like property/fields & nothing else). I have manually implemented interfaces for all my Entities and have created TypedList / TypedViews which implement this interface along with the original Entity via partial classes. This means that I can pass objects around my code and not worry about whether I'm passing an Entity or a TypedList etc...
You can't avoid fetching data if you need to fetch the data. Prefetch paths do that for you, so they don't gain anything if the actions to be taken by the prefetch path fetcher is the same as manual fetching (m:1, single entities). The advantage of prefetch paths is that it can pull related entities in a 1:n scenario out of the db in 1 query and merge them for you. You can't do that manually. There you win performance. Typedlists fetch faster at the moment because they don't have the per-object overhead. The difference is greatly reduced in v2.
The designer should allow you to specify interfaces to implement as well. This is planned.
I also support hierachies of the interface so that I can pass in Entities based on a subset of columns. IAccountEntity implements IAccountSummary which in turn implements IAccountIdentifier. This makes my Fetch code based very flexible and performance is optimised by only fetching exactly what is required. If I have already fetched a full AccountEntity and only want to display its name for instance I can pass IAccountSummary to my methods since both an AccountEntity or an AccountSummary entity since implement IAccountSummary. etc.
Planned are 'fieldpaths' for fetches, which specify in a hierarchy, the fields to fetch. This can then be used to fetch all blobs for a set of entities for example, and merge them with the entities at hand. This reduces the initial fetch time and improves performance, especially in readonly scenario's.
Being able to specify these interfaces in the designer would be a dream and then I could even specify the return type from Stored Proceedures to be a set of IAccountSummary etc... This would give the business logic a complete abstraction from the underlying souce of the data.
Procs for persistence are on the list as well as selecting interfaces to implement. That is: interfaces to implement, so stubbing out methods in an interface you specify, IF specified you want it to stub out the interface (probably not). I've still think about if it's needed in the designer because we now have partial classes, so it's not really a big deal anymore.
[UPDATE] AND HOW DID I FORGOT - the MOST important missing feature - Batch updates to the DB via UnitOfWork and SaveEntityCollection!
Batching won't be supported for now, as it will take quite a piece of custom code to manage it all, and I've already explained to you why it is very hard to get this right in a hierarchical scenario, if not undoable.