This project is read-only.

Querying ContentManager inside an event from IShapeTableProvider

Topics: Core, Writing modules, Writing themes
Jul 6, 2013 at 12:50 AM
Edited Jul 6, 2013 at 1:09 AM
Hi, I am getting an orchard error when trying to add a list of contentparts to a shape that is built in this way:
I am getting the onCreated event successfully inheriting from IShapeTableProvider.

The issue is that when i make this query i get an error. This query works fine outside the discover function. I think it has to be with some context conflict. In general, the queries from ContentManager class don't work here.
builder.Describe("BreadcrumbsProjects").OnCreated(displaying =>
                    var query = Services.ContentManager.Query(new string[]{"Project"}).List().ToList();                 
                    displaying.Shape.ProjectPart = query;
Please believe me, everything is ok. The query works fine outside the event, but i need to add the contentparts to that shape, i need it that way!

It works if i don't force to query the items using ToList() or List();

I tried to use IRepository and it worked, but i don't know how to convert from ContentPartRecord to ContentPart, i tried using custom services. I have seen every implementation of the IShapeTableProvider on the Orchard Modules and i did not find any clue about inserting queries in a Shape event.

The error happens in DefaultContentQuery.cs in Line 146:
 return criteria
                .Select(x => ContentManager.Get(x.ContentItemRecord.Id, _versionOptions != null && _versionOptions.IsDraftRequired ? _versionOptions : VersionOptions.VersionRecord(x.Id)))
Here is the the error thrown:

While preparing SELECT this_.Id as Id244_2_, this_.Number as Number244_2_, this_.Published as Published244_2_, this_.Latest as Latest244_2_, this_.Data as Data244_2_, this_.ContentItemRecord_id as ContentI6_244_2_, contentite1_.Id as Id243_0_, contentite1_.Data as Data243_0_, contentite1_.ContentType_id as ContentT3_243_0_, contenttyp2_.Id as Id245_1_, contenttyp2_.Name as Name245_1_ FROM Orchard_Framework_ContentItemVersionRecord this_ inner join Orchard_Framework_ContentItemRecord contentite1_ on this_.ContentItemRecord_id=contentite1_.Id inner join Orchard_Framework_ContentTypeRecord contenttyp2_ on contentite1_.ContentType_id=contenttyp2_.Id WHERE contenttyp2_.Name in (@p0) and this_.Published = @p1 an error occurred

Someone understands what is happening?
Jul 6, 2013 at 2:47 AM
This is really not the right place to query the database. Why do you need to do that?
Jul 6, 2013 at 10:47 AM
Make sure that the Services you inject is resolved per request. If you inject it and store it as a private field, that instance will be used across requests, but the DB context will be long disposed. The reason for this is that IShapeTableProviders are stored in a list of a singleton class (DefaultShapeTableManager).

Instead, inject Work<IOrchardServices>.
Jul 6, 2013 at 4:58 PM
Edited Jul 6, 2013 at 4:59 PM
Bertrand, I just need to pass some items to a shape that needs them to render on a view.. Is there another way? I also could make an ajax call to a controller.. but i was looking a better way using orchard pipeline system. I tried to understand how Menu items are added to the shape but i could not get it. The easiest way i found was using IShapeTableProvider. Any suggestion Bertrand?

For now i will try to figure it out how to do it injecting Work<IOrchardServices> Instead IOrchardServices. I will let you know if it works this way.

Thanx a lot skywalker!
Jul 6, 2013 at 5:07 PM
Are you creating a custom menu item type?
Jul 6, 2013 at 7:29 PM
If that shape needs the data, why isn't it queried by whatever entity created the shape? What created the shape?
Jul 8, 2013 at 2:57 PM
I am creating a custom breadcrumbs. The shape is created inside other shape and the parent shape is an alternate for menu widget. But it is an alternate added also using IShapeTableProvider.
Jul 8, 2013 at 3:22 PM
Hey, Skywalker!! It worked, i just injected Work<IOrchardServices> instead IOrchardServices and it worked perfectly. Thx so much!!
Jul 8, 2013 at 9:12 PM
If it's grafting onto menu, why not add your own handler or driver to menu, rather than implement a shape table provider?
Jul 8, 2013 at 9:24 PM
You mean to override directly MenuWidget Driver from source code project? or how i do it from my module? can you show me?
Jul 8, 2013 at 11:24 PM
You don't need to override it. There can be more than one driver for a part. Just create a new one from your module.
Jul 9, 2013 at 4:18 PM
Thx Bertrand, i think the best way to do this task is creating a driver in my module for the MenuWidgetPart!!

Both answers were great, thx too much!!