ServiceStack SelectLazy<long> System.NullReferenceException - servicestack

using (IDbConnection db = dbFactory.OpenDbConnection()) {
List<long> x = db.SelectLazy<long>(
"SELECT Id FROM MyTable").ToList();
}
Why is x null?
It works when I use Select instead of SelectLazy, or when I use SelectLazy on the entire row and not just the Id.

In OrmLite you use different API's to match the results you're after, e.g:
Select* API's for returning a List<MyTable>
Column* API's for returning a column of field values, e.g List<long>
Single* API's for returning a Single Row, e.g Table
Scalar* API's for returning a Single field value, e.g long
So to select a column as a List of fields you use db.Column, e.g:
var results = db.Column<long>(db.From<MyTable>().Select(x => x.Id));
These also have Raw Sql* equivalents, e.g:
var results = db.SqlColumn<long>("SELECT Id FROM MyTable");

Related

GUIDEWIRE : How to display the the query builder result in UI?

I am using query builder to return number of search result from the database table. Now I would like to display the result in the UI by only first three rows. How can I achieve this?
QueryAPI is lazy, when .toList(), .toTypedArray(), .toCollection(), .where(), etc occurs all resultset is retrieved (eager).
I recommend you to use this:
var limit = 3
var rs = Query.make(entity.XXX)...select()
rs.setPageSize(limit)
var paginatedRS = com.google.common.collect.Iterables.limit(rs,limit)
setPageSize method specifies how many rows will be fetch "by page"
limit method make a new iterator that have only the first (limit) rows

Unable to retrieve custom list value from saved search in netsuite

Creating saved search in suitescript using nlapiSearchRecord. All the column value returns except one column which is type is custom list.
How could I get value of custom list?
To get the value I'm using code lines below.
columns[0] = new nlobjSearchColumn( 'customlist' );
var searchresults = nlapiSearchRecord( 'customrecord', null, filters, columns );
To get the column value
var listValue = searchresult.getListValue( 'customlist' );
I assume you've simplified your code in trying to be clear or confidential but there will never be fields or records with those ids.
from a search you would do:
var searchResult = searchResults[0];
searchResult.getValue(fieldId, joinName, summary)
// or in your case
searchResult.getValue('customlist'); //returns id of list value or simple result of non-list/record fields
or (and I think this is the one you want)
searchResult.getText('customlist'); // returns the display value of the list/record field.

Need to find Max Value in Liferay table using Service Builder

I have built a Liferay portlet using Service Builder and it has one table. One of the fields holds a double value called 'ZValue'. I need to add to my -LocalServiceImpl.java file a public method that will return the maximum value currently found in the field 'ZValue'.
I was hoping there was a Liferay class similar to DynamicQuery that instead returns a single value. I know I can return all the records and cycle through them myself to get the maximum value, but I'm sure there is a simpler way to get the max value.
What I have found in my search of stackoverflow is:
DynamicQuery query = DynamicQueryFactoryUtil.forClass(classname);
query.setProjection(ProjectionFactoryUtil.max("ZValue"));
but I didn't understand how to actually return the value as a DynamicQuery returns a list and not a single value.
In the following example, we query the JournalArticle table to find all the articles that match a certain criteria, and then only get the newest version of each of those (the max).
As Pankaj said, you need to create two dynamic queries. The first one is used to specify that you need the max to be returned:
DynamicQuery subQuery = DynamicQueryFactoryUtil.forClass(JournalArticle.class, "articleSub", PortalClassLoaderUtil.getClassLoader())
.add(PropertyFactoryUtil.forName("articleId").eqProperty("articleParent.articleId"))
.setProjection(ProjectionFactoryUtil.max("id"));
articleSub is just an alias you assign to the query. ProjectionFactoryUtil.max will return the max.
The second one is the actual query. It will take the value returned from the first query:
DynamicQuery query = DynamicQueryFactoryUtil.forClass(JournalArticle.class, "articleParent", PortalClassLoaderUtil.getClassLoader())
.add(PropertyFactoryUtil.forName("id").eq(subQuery))
.add(PropertyFactoryUtil.forName("type").eq("Slider"));
The execution of this DynamicQuery will return a List<JournalArticle> with all the matches returned by the generated SQL sentence.
List<JournalArticle> myList = JournalArticleLocalServiceUtil.dynamicQuery(query);
Liferay 7.2 dxp sp5
import com.liferay.portal.kernel.dao.orm.Criterion;
import com.liferay.portal.kernel.dao.orm.DynamicQuery;
import com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil;
import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
In my case I want to fetch maximum value of a column so I used this query
DynamicQuery dynamicQuery = MyTableLocalServiceUtil.dynamicQuery();
dynamicQuery.setProjection(ProjectionFactoryUtil.max("columnName1"));
DynamicQuery dynamicQuery2 = MyTableLocalServiceUtil.dynamicQuery();
dynamicQuery2.add(PropertyFactoryUtil.forName("columnName1").eq(dynamicQuery));
List<Object> dynamicQuery3 = MyTableLocalServiceUtil.dynamicQuery(dynamicQuery2);
This will return a list but having maximum value in column 'columnName1'.
Here one thing I observed that if columnName1 having more than one value which is maximum then it will return that number of columns.
Support if columnName1 having max value of 50 but 3 rows having 50 then it will return 3 objects inside the list.
Second case:
find max value of columnName1
and columnName2=anyValue
DynamicQuery dynamicQuery = MyTableLocalServiceUtil.dynamicQuery();
dynamicQuery.setProjection(ProjectionFactoryUtil.max("columnName1"));
DynamicQuery dynamicQuery2 = MyTableLocalServiceUtil.dynamicQuery();
dynamicQuery2.add(PropertyFactoryUtil.forName("columnName2").eq(anyValue));
dynamicQuery2.add(PropertyFactoryUtil.forName("columnName1").eq(dynamicQuery));
List<Object> dynamicQuery3 = MyTableLocalServiceUtil.dynamicQuery(dynamicQuery2);
In this case what I found that dynamic query making and operation of max value of columnName1 and columnName2=anyValue.
if a row where columnName2=anyValue doesn't have maximum value of columnName1 then it is returning empty list.

Using string in place of property name (LINQ)

I have been able to get the values from tables using linq.
var q=(from app in context.Applicant
where app.ApplicantName=="")
Now what I want is this:
var q=(from app in context.Applicant
where app.stringIhave =="") // so instead of column name I have string which has same name as column.
Is it possible to specify string in Select as this is not sure what I will get in each case, I need different data all the time.
Is it possible to do so?
If no, then I will figure out something else.
Update
I have a GlobalString, which holds the column name of a table.
So when I query that table, I only specify from string which column value I want to get:
var q=(from app in context.Applicants
where app.ID==1013
select GlobalString //which is specifying that I want to get value from which column, as column name is not fixed.
//where GlobalString can have values like: app.FirstName..app.LastName etc
Update1:
var q = context.Applicants.Select("new(it.ApplicantFirstName as FirstName, it.ApplicantLastName as LastName)");
Error Message:
The query syntax is not valid. Near keyword 'AS'
You can use Dynamic Linq (available from NuGet) for that:
var q = context.Applicant.Where(app.stringIhave + " = #0", "");
for select you can try something like this
var q = context.Applicant.Select("new(it.FirstName as FirstName, it.LastName as LastName)");
so you only need construct string for that format

What is the best way to retrieve distinct / unique values using SPQuery?

I have a list that looks like:
Movie Year
----- ----
Fight Club 1999
The Matrix 1999
Pulp Fiction 1994
Using CAML and the SPQuery object I need to get a distinct list of items from the Year column which will populate a drop down control.
Searching around there doesn't appear to be a way of doing this within the CAML query. I'm wondering how people have gone about achieving this?
Another way to do this is to use DataView.ToTable-Method - its first parameter is the one that makes the list distinct.
SPList movies = SPContext.Current.Web.Lists["Movies"];
SPQuery query = new SPQuery();
query.Query = "<OrderBy><FieldRef Name='Year' /></OrderBy>";
DataTable tempTbl = movies.GetItems(query).GetDataTable();
DataView v = new DataView(tempTbl);
String[] columns = {"Year"};
DataTable tbl = v.ToTable(true, columns);
You can then proceed using the DataTable tbl.
If you want to bind the distinct results to a DataSource of for example a Repeater and retain the actual item via the ItemDataBound events' e.Item.DataItem method, the DataTable way is not going to work. Instead, and besides also when not wanting to bind it to a DataSource, you could also use Linq to define the distinct values.
// Retrieve the list. NEVER use the Web.Lists["Movies"] option as in the other examples as this will enumerate every list in your SPWeb and may cause serious performance issues
var list = SPContext.Current.Web.Lists.TryGetList("Movies");
// Make sure the list was successfully retrieved
if(list == null) return;
// Retrieve all items in the list
var items = list.GetItems();
// Filter the items in the results to only retain distinct items in an 2D array
var distinctItems = (from SPListItem item in items select item["Year"]).Distinct().ToArray()
// Bind results to the repeater
Repeater.DataSource = distinctItems;
Repeater.DataBind();
Remember that since there is no CAML support for distinct queries, each sample provided on this page will retrieve ALL items from the SPList. This may be fine for smaller lists, but for lists with thousands of listitems, this will seriously be a performance killer. Unfortunately there is no more optimized way of achieving the same.
There is no DISTINCT in CAML to populate your dropdown try using something like:
foreach (SPListItem listItem in listItems)
{
if ( null == ddlYear.Items.FindByText(listItem["Year"].ToString()) )
{
ListItem ThisItem = new ListItem();
ThisItem.Text = listItem["Year"].ToString();
ThisItem.Value = listItem["Year"].ToString();
ddlYear.Items.Add(ThisItem);
}
}
Assumes your dropdown is called ddlYear.
Can you switch from SPQuery to SPSiteDataQuery? You should be able to, without any problems.
After that, you can use standard ado.net behaviour:
SPSiteDataQuery query = new SPSiteDataQuery();
/// ... populate your query here. Make sure you add Year to the ViewFields.
DataTable table = SPContext.Current.Web.GetSiteData(query);
//create a new dataview for our table
DataView view = new DataView(table);
//and finally create a new datatable with unique values on the columns specified
DataTable tableUnique = view.ToTable(true, "Year");
After coming across post after post about how this was impossible, I've finally found a way. This has been tested in SharePoint Online. Here's a function that will get you all unique values for a column. It just requires you to pass in the list Id, View Id, internal list name, and a callback function.
function getUniqueColumnValues(listid, viewid, column, _callback){
var uniqueVals = [];
$.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_layouts/15/filter.aspx?ListId={" + listid + "}&FieldInternalName=" + column + "&ViewId={" + viewid + "}&FilterOnly=1&Filter=1",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" }
}).then(function(response) {
$(response).find('OPTION').each(function(a,b){
if ($(b)[0].value) {
uniqueVals.push($(b)[0].value);
}
});
_callback(true,uniqueVals);
},function(){
_callback(false,"Error retrieving unique column values");
});
}
I was considering this problem earlier today, and the best solution I could think of uses the following algorithm (sorry, no code at the moment):
L is a list of known values (starts populated with the static Choice options when querying fill-in options, for example)
X is approximately the number of possible options
1. Create a query that excludes the items in L
1. Use the query to fetch X items from list (ordered as randomly as possible)
2. Add unique items to L
3. Repeat 1 - 3 until number of fetched items < X
This would reduce the total number of items returned significantly, at the cost of making more queries.
It doesn't much matter if X is entirely accurate, but the randomness is quite important. Essentially the first query is likely to include the most common options, so the second query will exclude these and is likely to include the next most common options and so on through the iterations.
In the best case, the first query includes all the options, then the second query will be empty. (X items retrieved in total, over 2 queries)
In the worst case (e.g. the query is ordered by the options we're looking for, and there are more than X items with each option) we'll make as many queries as there are options. Returning approximately X * X items in total.

Resources