2

Lets say that I have a class called Stock and which has a virtual ICollection Prices, which is a historical set of prices.

If you fetch a stock and after the stock is materialized you query the Prices but apply a filter like mystock.Prices.OrderByDescending(px => px.Date).First(), EF internally loads all the prices and then it applies the filters used, since prices could be a large collection, I would really like to see EF just load the price that matched my where criteria. Basically applying the filtering at the server end rather than client side.

Is it possible to do this?

Thanks

1
  • it's not possible with lazy loading, but you can do it when you load the entity initially (by projecting to an anonymous type with the data you want) Commented Apr 23, 2012 at 21:31

1 Answer 1

2

It's possible, but this way only works if you can assume Prices is really an EntityCollection rather than some other class that also happens to implement ICollection. I'm not sure if this is true in all supported EF scenarios. The function to use is EntityCollection's CreateSourceQuery function.

((EntityCollection<Price>)stock.Prices).CreateSourceQuery().OrderByDescending(price => price.Date).First();

If that doesn't work for you, another possibility might be to go back to the context, and query from there:

(from price in context.Prices
 where price.StockId == stockId
 orderby price.Date descending
 select price).First();
Sign up to request clarification or add additional context in comments.

7 Comments

In my case it is a HashSet, I'm using CodeFirst so not sure if I have a choice in how to get a EntityCollection rather than a HashSet. public virtual ICollection<Price> Prices { get; set; } so EF is somehow filling it via proxy when the property is accessed.
@user661486 Looking a bit further into this, that can happen if you're using POCO classes, and either your classes don't meet the requirements for change tracking (the class should be public, unsealed, and the property accessors should be virtual) or you've disabled proxy classes. Well, in that case, the second of the options is probably an easier way to go.
class is public, accessor is virtual, the only thing left is proxy classes, unless they are disabled by default, I haven't done anything to disable them, but a proxy is probably there because the collection load happens at the time I use the variable, so it is lazy loading.
@user661486 Are all property accessors virtual? There are two separate actions for proxy creation, and if only one is possible, only that one will take place. The first is lazy loading, which requires your navigation properties to be virtual. The second is change tracking, which requires all your properties (including your scalar properties) to be virtual. EntityCollections only get used when change tracking is also enabled.
@user661486 See pastebin.com/Tn97fMxv for a minimal Code First sample showing an EntityCollection.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.