how to get all content items of a special content type in orchad core - orchardcore

I'm working with orchard core and I've written my own Apis.
To get content items of a special content type I've used GetRecentContentItemsByContentTypeAsync() function. this function does not get all content items, but I need to get all to write a service with pagination.
I would appreciate it if there is a solution...
Thanks in advance

You probably will want to use inject the YesSql.ISession directly to create a more specific query.
Something like
var query = _session.Query<ContentItem, ContentItemIndex>(x => x.ContentType == "mycontenttype");
var count = await query.CountAsync(); // for pagination
var results = await query.Skip(0).Take(10).ListAsync();
or for a more complex set
using YesSql.Services;
var contentTypes = new [ "contenttype1", "contenttype2" ];
var query = _session.Query<ContentItem, ContentItemIndex>(x => x.ContentType.IsIn(contentTypes));

Related

Firestore Pagination query on collection group data

Description: I want to implement infinite scroll in React-Native with firebase and i want to paginate on collection group data for instant result in my app. Error is shown in screenshot.
My code:
var ref = firestore().collectionGroup('user_posts').orderBy('time_stamp', 'desc').limit(5);
ref.get().then(snapshot => {
var posts = []
var lastVisible = snapshot.docs[snapshot.docs.length - 1];
this.setState({ last_Visible: lastVisible });
});
var next = firestore().collectionGroup('user_posts').orderBy('time_stamp', 'desc')
.startAfter(this.state.last_Visible)
.limit(5);
next.get()
.then(FirestoreDocumentSnapshot => {
var lastVisible = FirestoreDocumentSnapshot.docs[FirestoreDocumentSnapshot.docs.length - 1];
this.setState({ last_Visible: lastVisible });
})
Please help, what i am doing wrong?
From a first look at the error and your code it seems like either the fields that you are referring to are empty, or the lastVisible should be an even number.
Try checking that you don't have empty fields in your docs and try removing the -1 from lastVisible.
Here you can check the proper way to use startAfter() which is the cause of your issue.
As you're sorting by time_stamp, you should specify that field in the query like so:
.startAfter(this.state.last_Visible.data().time_stamp)
Here is an example from the official documentation. (From the language tabs choose Node.js)

How to configure links with HasNavigationPropertiesLink after latest WebAPI beta (26-Jun-2013) Update

I have a basic POCO (No database) structure implementing an OData Service with the latest WebAPI update. Unfortunately, the latest update broke the HasNavigationPropertiesLink code that I had to generate links which can be used for $expand operations. Here is my old code:
var jobs = modelBuilder.EntitySet<Job>("Jobs");
jobs.EntityType.NavigationProperties,
(entityContext, navigationProperty) => new
Uri(entityContext.UrlHelper.Link(ODataRouteNames.PropertyNavigation,
new
{
Controller = "Jobs",
parentId = entityContext.EntityInstance.ID,
NavigationProperty = navigationProperty.Name
})));
And here is my new code (that doesn't work):
var jobs = modelBuilder.EntitySet<Job>("Jobs");
jobs.EntityType.NavigationProperties,
(entityContext, navigationProperty) => new
Uri(entityContext.Url.Link(<??WHAT GOES HERE??>,
new
{
Controller = "Jobs",
parentId = entityContext.EdmObject,
NavigationProperty = navigationProperty.Name
})),
true);
Any help is much appreciated - this doesn't seem to have been documented in the updates.
looks like the version of the OData bits you are using is very old. In our current version, you can use the ODataConventionsModelBuilder to create a model that defines navigation properties and links following conventions, so unless you need to generate custom links, it's a better way to go. However, if you want to generate a custom navigation link, the link generation code looks something similar to this:
var jobs = builder.EntitySet<Job>("Jobs");
jobs.HasNavigationPropertiesLink(customers.EntityType.NavigationProperties,
(context, navigationProperty) =>
{
var result = "http://mydomain.com/prefix/odataPath";
//In order to generate this link you can use context.Url.ODataLink(new EntityPathSegment("Jobs"), ...);
return new Uri(result);
}, followsConventions: true);
it is better to use ODataConventionsModelBuilder as Javier has suggested. But if you still want to set up your own odata model you can do it:
var jobs = builder.EntitySet<Job>("Jobs");
jobs.HasNavigationPropertiesLink(customers.EntityType.NavigationProperties,
(context, navigationProperty) => context.GenerateNavigationPropertyLink(navigationProperty, false)
, followsConventions: true);

Render conditional templates with Twig

I've a layout template with a left sidebar where I show information of Location passed entities as an array.
Also in this template, I show a object Map with all of this locations.
I want to do click on a Location of my sidebar and then on the same template show another object Map replacing the previous with information of this Location. Keeping the sidebar with the information and not doing new queries on the database.
How to achieve this?
Ajax? Conditional layout?
I read this article but I don't understand how to solved my problem: http://twig.sensiolabs.org/doc/recipes.html#overriding-a-template-that-also-extends-itself
PD: I'm using Twig template and Symfony2
You could have a separate template for printing object map and, as you guessed, this would have to be done using AJAX. You would pass the data you want to show on map (not id as you don't want to query database again) and the controller would return formatted HTML.
However, this seems to me a bit overkill. I would always consider doing JS (with optional framework) in order to swap the content of sidebar with Map object.
It really depends on which map API do you use. If it could be controlled via JS I would look no further. It it could not, well then, AJAX is your natural choice....
UPDATE:
OK, what you should do is create initial Map object that will be modified later on:
var theMap = null;
function initializeMap(){
var mapOptions = {
center: new google.maps.LatLng(some_latitude, some_longitude),
zoom: 8, // goes from 0 to 18
mapTypeId: google.maps.MapTypeId.ROADMAP
};
theMap = new google.maps.Map(document.getElementById("map_canvas"),mapOptions);
// you must have some element with ID = 'map_canvas'
}
some_latitude and some_longitude are fairly unimportant as you will most likely set new coordinates in a few moments.
Now assuming (but not crucial at all) that you use some of the JS frameworks (I prefer jQuery) you could bind click event to those location links:
var onlyMarker = null;
$('.location').click(function(){
var $t = $(this);
var newLatLang = new google.maps.LatLng($t.attr('data-lat') ,$t.attr('data-lng'));
if ( onlyMarker == null ) {
onlyMarker = new google.maps.Marker({
position: newLatLang
map: theMap,
title: $t.attr('title')
});
}else{
onlyMarker.setPosition(newLatLang);
}
});
Now, relying on HTML5's 'data-*' attibutes is not good idea in particular as if you use any other version lower you will most likely end-up with invalid markup. The workaround is to for link (<a>) to carry id/key to LatLng object, for example:
// initially generated from `AJAX` or in `Twig` loop
var allLatlangs = [
new google.maps.LatLngf(some_latitude, some_longitude),
new google.maps.LatLngf(some_latitude, some_longitude),
new google.maps.LatLngf(some_latitude, some_longitude),
];
$('.location').click(function(){
var id = $(this).attr('id');
var newLatLang = allLatLang(id);
//....
// everything else is the same
// ....
});
Don't forget to include Maps API with proper API key:
https://maps.googleapis.com/maps/api/js?key=API_KEY_HERE&sensor=true
In order to obtain valid API key follow this link: API KEY HOW-TO
This link basically covers key steps that I have described here so study it and it should all come together nicely.
Also, if you're unsure how to retrieve some things from Maps you should consult reference:
REFERENCE which has every method call described pretty good
Remember not to execute any of this code until everything is being loaded.
Hope this helped a bit :)

Correctly structuring this LinqToSql code

Normally I use stored procedures / work in SQL so apologies if I get the terminology slightly off here..
I have a database, with 3 seperate tables, and I need to search multiple fields in each of the 3 tables.
Im sure that I am not doing this the mose effective way, initially I am trying to do it in simple seteps to understand it.
I have the following;
var foo1 = entities.table1.Where(a => a.bodyText.Contains(searchString) || a.pageTitle.Contains(searchString));
var foo2 = entities.table2.Where(b => b.newsArticle.Contains(searchString) || b.newsArticle.Contains(searchString));
var foo3 = entities.table3.Where(c => c.ImageDescriptionContains(searchString));
I need to combine all these results into a single repeater for display.
At this point all 3 sets of data are in seperate, unique collections of anonymous data. So whats the best way of converting these into a single coherent bindable source?
I was thinking of itereating through each list in turn, pulling out the fields I need to display and putting them in a new class, then binding a lsit of these classes to the repeater.
But it all seems a bit clunky to me.
Is there a way of doing the search across all 3 tables in one go, and returning just the fields I need from each table, with a common name (i.e. in SQL I could write
select b.newsArticle as myText,
or
select newsArticle, ''
to return the news article and an empty string).
This would combine:
var foos = foo1.ToList();
foos.AddRange(foo2);
foos.AddRange(foo3);
To get just what you want:
var myExtractedValues = foos.Select(x => new {
Article = !string.IsNullOrEmpty(x.newsArticle))
? x.newsArticle
: string.Empty});
I have used an anonymous type here but you could swap the new {} with a type of your own.
I reverse the operator on the IsNullOrEmpty but that is just a personal preference (I prefer how is reads.)
To get all the results in one go you'll need to define a common class that will be used by all three queries to store the result. This class may be as well anonymous but I'll name it just for clarity.
class Data
{
public string Text{ get; set;}
}
Now, in your code you'll fetch instances of Data from database and you can use Union:
using( var entities = new YourDataContext)
{
var foo1 = entities.table1
.Where(a => a.bodyText.Contains(searchString) ||
a.pageTitle.Contains(searchString))
.Select(a => new Data{ Text = a.bodyText});
var foo2 = entities.table2
.Where(b => b.newsArticle.Contains(searchString) ||
b.newsArticle.Contains(searchString))
.Select(b => new Data{ Text = b.newsArticle});
var foo3 = entities.table3
.Where(c => c.ImageDescription.Contains(searchString))
.Select(c => new Data{ Text = c.ImageDescription});
return foo1.Union(foo2).Union(foo3);
}

Incorrect joining of tables in linq

I have these entities:
Account
-IdAccount: 1
-Money: 20
-IdInfo: 2
Navigation Property: Info
Info
-IdInfo: 2
-Info: hi
Navigation Property: Account
When I do something like this using linq
var account = storeDB.Accounts.Include("Info").Single( a => a.IdInfo == 2 );
This will do a join with IdAccount=1 and IdInfo= 1, instead of 2. Does anybody know a different way I can do a query? I looked at select from bla bla, but I dont know how to put that in an object, since I created an Account.cs, and Info.cs like the ASP MVC3 tutorial of music.
I have a feeling it does some sort of natural join and that's why it associates both Ids with number 1.
I have been checking this for a lot of hours, and haven't been able to resolve this, any help will be greatly appreciated!
Please try using .Where( a => a.IdInfo == 2).Single();
Assuming you're using Linq-to-Sql, try:
using (var storeDB = new DataContext())
{
var options = new DataLoadOptions();
options.LoadWith<Accounts>(a => a.Info);
db.LoadOptions = options;
var account = from a in storeDB.Accounts
where a.IdInfo == 2
select a;
}
This answer will provide som extra information: How do you construct a LINQ to Entities query to load child objects directly, instead of calling a Reference property or Load()

Resources