问题
There is a Custom Content Type "SideBarLinks" in CMS. I created a query to get the list of items of this type: "SideBarLinks" and specified sort and filter criteria as well. This works fine when Previewing the query results in CMS.
Is there a way i can get the same list in code, say in the Action method of any Controller ? Which Class/Services of Orchard is there to query ? And how to perform all those filtering, sorting of the Query results in a Controller method ?
So far I used to query Content items using below codes i have referred through Blogs and other Forum. Full credit to them. This seems to initialize the IOrchardServices
and using this service get the items.
public IOrchardServices Services { get; private set; }
public AdminController(IOrchardServices services, IShapeFactory shapeFactory) {
Services = services;
T = NullLocalizer.Instance;
Logger = NullLogger.Instance;
Shape = shapeFactory;
}
This is the Action Method:
public ActionResult List(int id) {
List<ContentItem> query = Services.ContentManager.GetAllVersions(id).ToList();
if (!query.Any()) {
return HttpNotFound();
}
return View(query);
}
How to get items specific to a Query ?
回答1:
That's a pretty broad question. I would definitely say the best place to start is in the source code, the answer is almost always in the source.
But here goes. The first thing you need is the content manager.
private readonly IContentManager _contentManager;
public MyController(IContentManager contentManager) {
_contentManager = contentManager;
}
To get a list of a specific content type
_contentManager.Query(VersionOptions.Published, "SideBarLinks").List();
To get a list of content items by a specific part
_contentManager.Query<UserPart, UserPartRecord>().List();
To get a list and filter it
_contentManager.Query<UserPart, UserPartRecord>().ForVersion(VersionOptions.Latest).Where(e => e.UserName = "Bob").List();
To filter by a different part
_contentManager.Query<UserPart, UserPartRecord>()
.Join<CommonPartRecord>()
.Where(e => e.CreatedUtc > DateTime.Now.AddDays(-1))
.List();
To load more data during the query that we will need later for displaying
_contentManager.Query<UserPart, UserPartRecord>()
.WithQueryHints(new QueryHints().ExpandParts<ExtraUserPart>())
.List();
I think a decent understanding of how Orchard works is important for building queries. Orchard is a very lazy system, it just wont go and join record tables if it isn't told to. And due to the fact that it can store part (if you tell it to) and field data in XML, unless you need to filter or order your data, you don't need to worry about anything, Orchard has all the data you need. If you do have data stored in record classes that you want to access later, Orchard will have to lazily load it later, resulting in more db queries and severe performance loss.
回答2:
If you want to get the content items that are linked to a specific query in your dashboard, you can do the following:
inject projectionmanager:
private readonly IProjectionManager _projectionManager;
public MyController(IProjectionManager projectionManager) {
_projectionManager = projectionManager;
}
get content items of specific query:
var contentItems = _projectionManager.GetContentItems(someQueryId);
If you take a look at Orchard.Projections/Controllers/AdminController you can see the preview action in here:
public ActionResult Preview(int id) {
if (!Services.Authorizer.Authorize(Permissions.ManageQueries, T("Not authorized to manage queries")))
return new HttpUnauthorizedResult();
var contentItems = _projectionManager.GetContentItems(id, 0, 20);
var contentShapes = contentItems.Select(item => _services.ContentManager.BuildDisplay(item, "Summary"));
var list = Shape.List();
list.AddRange(contentShapes);
return View(list);
}
来源:https://stackoverflow.com/questions/33033190/how-to-get-the-query-preview-list-in-code-orchard-1-7