- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
V2.6 and Linq to Objects
Joined: 14-Dec-2003
Frans, Based on your blog posts and a few messages here, I believe, v2.6 will center around providing a Sql to LlblGen Entity/EntityCollection layer that uses Linq syntax to fill and save from the database.
For me, the Linq to Objects, (or in memory manipulation of Entity Collections and Entity Views) is the interesting area. Today, to use linq with LlblGen, I am using the Cast or TypeOf extension methods since the collections I use don't support IEnumerabl<T>.
Will this interface be supported in v2.6?
Would you discuss what we should expect to see related to Linq to Objects?
Thanks.
The main focus is indeed on providing a querying methodology similar to our own query api for reading data from the db.
There are indeed other areas where Linq and thus linq to objects, can be used, for example with filters/sorters in entityviews and general usage of collections in linq queries.
The collections implement IEnumerable, not IEnumerable<T>. I haven't done any testing with linq to objects and entity collections yet, so you can't use the collection usefully, because type information is lost and you therefore have to cast all over the place?
I've added IEnumerable<T> to CollectionCore<T>, so all collections now implement it (in v2.6). If you're working with IEntityCollection(2) typed parameters, you can only use IEnumerable, which is logical, as there's no type argument in the interface.
The main challenge with adding code for linq to objects is to avoid needing a specific .NET 3.5 build library version. All linq stuff is now in a separate dll, so the ormsupportclasses are still .net 2.0 build (as .net 3.5 is the .net 2.0 CLR anyway), so it might be it will be more difficult to add linq-based filters to views but we'll see about that after the Linq to LLBLGen Pro ctp (hopefully next week, hierarchical fetches of dynamic lists (lists of anonymoustypes) is still not done) has been released what should be added as well.
Joined: 14-Dec-2003
The collections implement IEnumerable, not IEnumerable<T>. I haven't done any testing with linq to objects and entity collections yet, so you can't use the collection usefully, because type information is lost and you therefore have to cast all over the place?
My code looks like this
IEntityCollection2 _collection = fitc.PayLoad[typeof (InvoiceTracker01Entity)];
IEntityView2 work;
work = _collection.CreateView();
var result3 = from invoice in [b]work.Cast<InvoiceTracker01Entity>()[/b]
where (invoice.CurrentActivityId == 7)
group invoice by new { invoice.BaseFormat } into currentActivities
orderby currentActivities.Key.BaseFormat
select new
{
BaseFormat = currentActivities.Key.BaseFormat,
InBalanceInvoices = currentActivities.Sum(invoice => invoice.IsInBalanceCount),
OutOfBalanceInvoices = currentActivities.Sum(invoice => invoice.IsOutOfBalanceCount),
UnknownBalanceInvoices = currentActivities.Sum(invoice => invoice.BalanceUnknownCount)
};
gridControl1.DataSource = [b]result3.ToList()[/b];
aurgumentDataMember = "BaseFormat";
So the casting isn't too much but i'm concerned about the efficiency of work.Cast<InvoiceTracker01Entity>() and that it enumerates the view at that poin rather than waiting until the rustult3.ToList() line is run.
The main challenge with adding code for linq to objects is to avoid needing a specific .NET 3.5 build library version. All linq stuff is now in a separate dll, so the ormsupportclasses are still .net 2.0 build (as .net 3.5 is the .net 2.0 CLR anyway), so it might be it will be more difficult to add linq-based filters to views but we'll see about that after the Linq to LLBLGen Pro ctp
Could it be done with extension methods in a seperate dll, so the 3.5 stuff would reside there?
As an alternative, for my use anyway, aggregates on entity views would eliminate much of my need for Linq (at least right now).
arschr wrote:
The collections implement IEnumerable, not IEnumerable<T>. I haven't done any testing with linq to objects and entity collections yet, so you can't use the collection usefully, because type information is lost and you therefore have to cast all over the place?
My code looks like this
IEntityCollection2 _collection = fitc.PayLoad[typeof (InvoiceTracker01Entity)]; IEntityView2 work; work = _collection.CreateView(); var result3 = from invoice in [b]work.Cast<InvoiceTracker01Entity>()[/b] where (invoice.CurrentActivityId == 7) group invoice by new { invoice.BaseFormat } into currentActivities orderby currentActivities.Key.BaseFormat select new { BaseFormat = currentActivities.Key.BaseFormat, InBalanceInvoices = currentActivities.Sum(invoice => invoice.IsInBalanceCount), OutOfBalanceInvoices = currentActivities.Sum(invoice => invoice.IsOutOfBalanceCount), UnknownBalanceInvoices = currentActivities.Sum(invoice => invoice.BalanceUnknownCount) }; gridControl1.DataSource = [b]result3.ToList()[/b]; aurgumentDataMember = "BaseFormat";
So the casting isn't too much but i'm concerned about the efficiency of work.Cast<InvoiceTracker01Entity>() and that it enumerates the view at that poin rather than waiting until the rustult3.ToList() line is run.
If you used EntityCollection<InvoiceTracker01Entity> instead of IEntityCollection2 and used that as the source of your query, it might work with v2.6. With the untyped IEntityCollection2 interface, you don't have a type specification, so I doubt it will work without the cast. Linq to objects isn't the fastest btw, MS is currently busy optimizing the linq to objects code, but don't be surprised that our own predicates are faster in-memory.
The main challenge with adding code for linq to objects is to avoid needing a specific .NET 3.5 build library version. All linq stuff is now in a separate dll, so the ormsupportclasses are still .net 2.0 build (as .net 3.5 is the .net 2.0 CLR anyway), so it might be it will be more difficult to add linq-based filters to views but we'll see about that after the Linq to LLBLGen Pro ctp
Could it be done with extension methods in a seperate dll, so the 3.5 stuff would reside there?
As an alternative, for my use anyway, aggregates on entity views would eliminate much of my need for Linq (at least right now).
![]()
Aggregates on views in our own framework won't happen, it's really complex to do and actually redundant with linq to objects available. Also, views are for viewing entities, so aggregates show rows of data in new tuples, not entities.
Extension methods aren't going to work here I think, or we might be talking about different things What I meant was teh filters and sorters specified to create a view on a collection. You now specify a predicateexpression and a sortexpression. What should be possible is produce a view on a collection produced by a linq query on the collection, so the result of the linq query on the collection is the view.
A linq to objects query is really just a delegate (Func<T, ...>), the challenge is to call it efficiently, thus with a known signature so code internally can do Invoke(param1, ..) instead of DynamicInvoke(...) which is dogslow.
This is also how I managed to add delegates build with lambdas to projectors in .NET 2.0 code
So looking at your code, I don't think you need the view. With IEnumerable<T> implemented on the collection, you could get rid of the cast and you don't need the view (you don't need it today as well, am I right?). With 2.6, you'll be able to perform this same query on the db as well.
Joined: 14-Dec-2003
So looking at your code, I don't think you need the view. With IEnumerable<T> implemented on the collection, you could get rid of the cast and you don't need the view (you don't need it today as well, am I right?). With 2.6, you'll be able to perform this same query on the db as well.
Two points: 1) I don't need the view for this, but, I've build other code to work off of views. 2) Hitting the database again for these summarizations of information I already would be bad for a number of reasons. Performance and the summary matching the detail being two that I can think of right off.
arschr wrote:
So looking at your code, I don't think you need the view. With IEnumerable<T> implemented on the collection, you could get rid of the cast and you don't need the view (you don't need it today as well, am I right?). With 2.6, you'll be able to perform this same query on the db as well.
Two points: 1) I don't need the view for this, but, I've build other code to work off of views.
Sure, and it should work with views AND entitycollections. I think the main issue is that if the type is IEntityView2, or IEntityCollection2, the compiler will require you to specify a cast as it can't determine what the real type is of the entity in the view or collection. So in these cases, if you want to avoid the cast, you should use EntityView<T> and EntityCollection<T>. This is something which can't be changed, as it would otherwise require a generic argument in IEntityCollection(2) which is making the whole interface void, as the interface is usable for accessing the collection without knowing the type of T
2) Hitting the database again for these summarizations of information I already would be bad for a number of reasons. Performance and the summary matching the detail being two that I can think of right off.
If you need to access the db again, then indeed it's expensive. If you don't need the set of entities for other purposes than this, it might be a better choice to do it in the db. The reason is that db's are optimized for this kind of work, and doing it in-memory using imperative loops can be slower (added to that that you've to transport the data outside the db.). So it's not a given that things are always faster in the db or always faster in the client, it depends on the situation.
arschr wrote:
So it's not a given that things are always faster in the db or always faster in the client, it depends on the situation.
Do you mean to say that there are things in life that aren't black or white? What a strange idea!
![]()
I hate to admit it, but in RARE edge cases, it indeed might be (I'm told)