Description: IMaterialize is Entity Framework materialization add-on. Deployment: In visual studio, next to your entity framework data model (.edmx) add new item from IMaterialize item template. You can either give it the name of your data model or choose any other name and then edit first line of the template to specify data model name. Usage: Whenever you have an IQueryable of plain EF entity, instead of calling .ToList(), you can work around EF, and materialize it via ADO.Net. Items are materialized without change tracking, lazy load navigation and any other EF features attached to them, as a tradeoff it works up to 5x faster depending on different conditions, like query complexity, EF settings an etc. code sample: IQueryable<client> query = context.Set<client>().Where(x => x.account_id != null); using (var materializer = new Materializer("myConnStringName")) { IEnumerable<client> output = materializer.Get(query); } Limitations: 1. Along with expected non-working EF features, .Distinct() and .Union() will not work the same way. If one DB table entry materialized from DB twice, for example via 2 different queries, you will have to manually filter repeating items either by their ids or full hash/compare. 2. So far it is tested on MS SQL server only and EF 5.0, might need some modifications to work with other DB providers of EF versions. 3. Source IQueryable cannot contain Union operations, since EF replaces field names in a request with C1, C2, and so on. so there is no way to match them by name. Other comments: Template uses the same code as EF template to parse .edmx file, but it generates different lines of code. Added in v2: To work around first limitation, generated equality comparers. If entity has identity field, only that field is included, otherwise all simple fields are compared. code sample: IEnumerable<client> distinct = materializer.Distinct(output); Added in v3: Added new method, for case where DB resides on different server and you want to reduce number of network calls. It allows to materialize requests in a single network roundtrip. Result loses generic parameters, so some additional effort is needed to put them back in. usage example: IQueryable<client> query1 = context.Set<client>().Where(x => x.account_id != null); IQueryable<account> query2 = query1.Select(x => x.account).Distinct(); using (var materializer = new Materializer("myConnStringName")) { var output = materializer.Materialize(new []{query1, query2}).ToArray(); var output1 = (IEnumerable<client>)output[0]; var output2 = (IEnumerable<account>)output[1]; } |