This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
I've made a simple model and now I'm trying to use WithAggregate() to load it. Unfortunately this error appears: System.InvalidOperationException : There is no method 'WithAggregate' on type 'Mindscape.LightSpeed.Linq.LightSpeedQueryOperators' that matches the specified arguments It's an 1:1 association between the entities and the aggregate is on the "Target Aggregates" property on the relation. Removing WithAggregate() from the query makes it work, but that's not really a fix. :) Maybe it's notable that the query is made on a List<T>.AsQueryable()? I'm not sure I understand aggregates fully as well. An aggregate can be on properties and relations, what is the point of putting it on a property? Thanks for your help! |
|
|
WithAggregate() will only work with LightSpeed queries, not with List<T>. Putting AsQueryable() on a List<T> doesn't turn it into a LightSpeed query. AsQueryable() really only does anything if you have an object which is IQueryable but happens to be stored in a variable of type IEnumerable. You therefore need to apply WithAggregate() to the LightSpeed query, NOT to the list that results from evaluating the query. (By the time you've populated the list, it's too late: the query has already run.) This query is typically obtained as a property on a strong-typed unit of work: // Eager-loads walruses associated with the penguins Obviously this can be combined with other operators: unitOfWork.Penguins.Where(...).OrderBy(...).WithAggregate(...); // still a LightSpeed query or using the LINQ syntax: (from p in unitOfWork.Penguins Regarding aggregates on properties: You apply an aggregate to a property when you want that property to lazy-load by default, but to have the option of eager-loading it. For example, consider a Video entity with a PreviewImage property that contains a high-resolution image (maybe several MB). When you're loading a list of Videos for display on a search results page, you don't want to waste time loading the PreviewImage for all of them, because you won't be displaying the high-resolution image in the list. But when the user clicks on one of the list items to go to a Details page, you *do* want to get the PreviewImage along with all the other details, in a single database query. So you'd put an aggregate on the PreviewImage field: [EagerLoad("WithDetails")] Then in your list page you'd write something like: unitOfWork.Videos.Where(...); and in your details page you'd write: unitOfWork.Videos.WithAggregate("WithDetails").Single(v => v.Id == id); Hope that makes sense now. |
|
|
Thanks for your nice answer and explanations, I suspected it only worked on LS queries. The problem is that I'm unit testing with a List<T> as Mock repository data. Is there any way workaround for this? |
|
|
If I've understood you correctly, you have real application code that looking like this: something.AsQueryable().WithAggregate(...).Maybe().Other().Operators(); That something comes from outside the method under test. In your real environment, something will be a LightSpeed query. In your test environment, something will be a List<T>. Is that correct? If so, I'm a bit stumped as to how you might work around it. A possible approach is to move the WithAggregate call to whatever is creating the something. Then the method under test will look like this: something.Maybe().Other().Operators(); And your real code will set something to blah.WithAggregate(...) and your test code will set it to a List<T>. If the WithAggregate() call is in your test code, then there are other options -- let me know if this is the case. |
|
|
Yes, that's exactly how it works for me! It's quite tricky, I'm using it in a ASP.NET MVC Controller which takes a IRepository<T> in the constructor. The interface exposes IQueryable<T> through an "Items" property. Hmm, maybe I can change that property to a method that takes an aggregate as an argument instead. That would work I guess but makes the interface a little bit less elegant, and closer tied to Lightspeed. The perfect solution eludes me as usual, but that's life, and Lightspeed rocks so I'm happy anyway. :) Thanks for your very quick help!
|
|