NHibernate query count - nhibernate

I am new to NHibernate and I want to have a count of rows from database. Below is my code,
SearchTemplate template = new SearchTemplate();
template.Criteria = DetachedCriteria.For(typeof(hotel));
template.Criteria.Add(Restrictions.Lt("CheckOutDate", SelDate) || Restrictions.Eq("CheckOutDate", SelDate));
template.Criteria.Add(Restrictions.Eq("Canceled", "False"));
int count = template.Criteria.SetProjection(Projections.Count("ID"));
It gives me an error when I try to compile app that says
"Cannot implicitly convert type 'NHibernate.Criterion.DetachedCriteria' to 'int'"
I want to have a count of rows of the table hotel..

You want to use GetExecutableCriteria:
SearchTemplate template = new SearchTemplate();
template.Criteria = DetachedCriteria.For(typeof(hotel));
template.Criteria.Add(Restrictions.Lt("CheckOutDate", SelDate) || Restrictions.Eq("CheckOutDate", SelDate));
template.Criteria.Add(Restrictions.Eq("Canceled", "False"));
var count = DoCount(template.Criteria, session /* your session */);
public long DoCount(DetachedCriteria criteria, ISession session)
{
return Convert.ToInt64(criteria.GetExecutableCriteria(session)
.SetProjection(Projections.RowCountInt64())
.UniqueResult());
}
On a side note, you should take a look at using NHibernate.Linq:
var result = (from h in Session.Linq<Hotel>()
where h.CheckOutDate <= SelDate
where h.Canceled != true
select h).Count();
More information here.

Related

How to use sql executeQuery method in groovy?

In groovy how can i use sql executeQuery method. In my below code i get the error as "Method executeQuery is protected in groovy.sql.Sql" on line 2. Please help!
def sql = new Sql(rdbDsService.getDataSource())
ResultSet rs=sql.executeQuery("select top 5 Id from MACHINES where (Total != Rightcount) order by FinishingTime");
order[0] = 0;
order[1] = 0;
order[2] = 0;
order[3] = 0;
count = 0;
while (rs.next())
{
order[count] = Integer.parseInt(rs["Id"].toString());
count = count + 1;
}
As per the message you're calling a protected method, the javadoc on the method states the following:
Useful helper method which handles resource management when executing
a query which returns a result set. Derived classes of Sql can
override "createQueryCommand" and then call this method to access the
ResultSet returned from the provided query or alternatively can use
the higher-level method of Sql which return result sets which are
funnelled through this method, e.g. eachRow, query.
Instead try using something like eachRow
sql.eachRow("select top 5 Id from MACHINES where (Total != Rightcount) order by FinishingTime") {
order[count] = it.Id
count = count + 1
}

How can use BETWEEN in sqlite via db.query

I've a query on sqlite that use "between" and I want to use it on standard Query.
my code is here:
String[] columns = new String[]{"_id", "question_group", "question_number", "is_answered"};
String selection = "question_group = ?";
String[] selectionArgs = new String[]{String.valueOf(category)};
String groupBy = null;
String having = null;
String orderBy = null;
String limit = null;
SQLiteDatabase db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READWRITE);
Cursor cursor = db.query(TABLE_QUESTION, columns, selection, selectionArgs, groupBy, having, orderBy, limit);
I want to Add another condition that is :question_number between 1 and 10. I can now write this query in a single statement but I want to use it as above I told.
From the Android documentation describing the selection parameter of the query() method:
A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given table.
If you want the following WHERE clause in your query
WHERE question_group = :category AND question_number BETWEEN 1 AND 10
then you can use the following selection and selectionArgs:
String selection = "question_group = ? AND question_number BETWEEN ? AND ?";
String[] selectionArgs = new String[]{ String.valueOf(category), "1", "10"};

Why can I not use Continuation when using a proxy class to access MS CRM 2013?

So I have a standard service reference proxy calss for MS CRM 2013 (i.e. right-click add reference etc...) I then found the limitation that CRM data calls limit to 50 results and I wanted to get the full list of results. I found two methods, one looks more correct, but doesn't seem to work. I was wondering why it didn't and/or if there was something I'm doing incorrectly.
Basic setup and process
crmService = new CrmServiceReference.MyContext(new Uri(crmWebServicesUrl));
crmService.Credentials = System.Net.CredentialCache.DefaultCredentials;
var accountAnnotations = crmService.AccountSet.Where(a => a.AccountNumber = accountNumber).Select(a => a.Account_Annotation).FirstOrDefault();
Using Continuation (something I want to work, but looks like it doesn't)
while (accountAnnotations.Continuation != null)
{
accountAnnotations.Load(crmService.Execute<Annotation>(accountAnnotations.Continuation.NextLinkUri));
}
using that method .Continuation is always null and accountAnnotations.Count is always 50 (but there are more than 50 records)
After struggling with .Continutation for a while I've come up with the following alternative method (but it seems "not good")
var accountAnnotationData = accountAnnotations.ToList();
var accountAnnotationFinal = accountAnnotations.ToList();
var index = 1;
while (accountAnnotationData.Count == 50)
{
accountAnnotationData = (from a in crmService.AnnotationSet
where a.ObjectId.Id == accountAnnotationData.First().ObjectId.Id
select a).Skip(50 * index).ToList();
accountAnnotationFinal = accountAnnotationFinal.Union(accountAnnotationData).ToList();
index++;
}
So the second method seems to work, but for any number of reasons it doesn't seem like the best. Is there a reason .Continuation is always null? Is there some setup step I'm missing or some nice way to do this?
The way to get the records from CRM is to use paging here is an example with a query expression but you can also use fetchXML if you want
// Query using the paging cookie.
// Define the paging attributes.
// The number of records per page to retrieve.
int fetchCount = 3;
// Initialize the page number.
int pageNumber = 1;
// Initialize the number of records.
int recordCount = 0;
// Define the condition expression for retrieving records.
ConditionExpression pagecondition = new ConditionExpression();
pagecondition.AttributeName = "address1_stateorprovince";
pagecondition.Operator = ConditionOperator.Equal;
pagecondition.Values.Add("WA");
// Define the order expression to retrieve the records.
OrderExpression order = new OrderExpression();
order.AttributeName = "name";
order.OrderType = OrderType.Ascending;
// Create the query expression and add condition.
QueryExpression pagequery = new QueryExpression();
pagequery.EntityName = "account";
pagequery.Criteria.AddCondition(pagecondition);
pagequery.Orders.Add(order);
pagequery.ColumnSet.AddColumns("name", "address1_stateorprovince", "emailaddress1", "accountid");
// Assign the pageinfo properties to the query expression.
pagequery.PageInfo = new PagingInfo();
pagequery.PageInfo.Count = fetchCount;
pagequery.PageInfo.PageNumber = pageNumber;
// The current paging cookie. When retrieving the first page,
// pagingCookie should be null.
pagequery.PageInfo.PagingCookie = null;
Console.WriteLine("#\tAccount Name\t\t\tEmail Address");while (true)
{
// Retrieve the page.
EntityCollection results = _serviceProxy.RetrieveMultiple(pagequery);
if (results.Entities != null)
{
// Retrieve all records from the result set.
foreach (Account acct in results.Entities)
{
Console.WriteLine("{0}.\t{1}\t\t{2}",
++recordCount,
acct.EMailAddress1,
acct.Name);
}
}
// Check for more records, if it returns true.
if (results.MoreRecords)
{
// Increment the page number to retrieve the next page.
pagequery.PageInfo.PageNumber++;
// Set the paging cookie to the paging cookie returned from current results.
pagequery.PageInfo.PagingCookie = results.PagingCookie;
}
else
{
// If no more records are in the result nodes, exit the loop.
break;
}
}

SQL Server CE update or insert query

In my Windows Forms application, I'm using a SQL Server Compact database. I have a function in which I want to update the columns 'id' and 'name' in table 'owner', unless the specified id does not exist, in which case I want new values inserted.
For example, my current table has 'id' 1 and 2. It MIGHT have 'id' 3. User enters data to insert/update id 3.
I want my query to do something like this:
UPDATE owner
SET name = #InputN
WHERE id = 3
IF ##ROWCOUNT = 0
INSERT INTO owner (id, name) VALUES 3, #InputN
How should I define my query in order to make this work in SQL Server Compact Edition?
You should do it in your form codes. This way you don't even need to check if there is an di with the value=3. It will check it by itself and update the row if it exists. If not you won't get any errors.
RSSql.UpdateNonQueryParametric("update owner set name=? where id=3", newname);
public static void UpdateNonQueryParametric(string query, params Object[] parameters)
{
SqlCeParameter[] param = new SqlCeParameter[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
param[i] = new SqlCeParameter();
param[i].Value = parameters[i];
}
_cnt = new SqlCeConnection();
_cnt.ConnectionString = ConnectionString;
_cmd = new SqlCeCommand();
_cmd.Connection = _cnt;
_cmd.CommandType = System.Data.CommandType.Text;
_cmd.CommandText = query;
_cmd.Parameters.AddRange(param);
if (_cnt.State != System.Data.ConnectionState.Open)
_cnt.Open();
_cmd.ExecuteNonQuery();
_cmd.Dispose();
if (_cnt.State != System.Data.ConnectionState.Closed)
_cnt.Close();
_cnt.Dispose();
}

LINQ: Count number of true booleans in multiple columns

I'm using LINQ to SQL to speed up delivery of a project, which it's really helping with. However I'm struggling with a few things I'm used to doing with manual SQL.
I have a LINQ collection containing three columns, each containing a boolean value representing whether an e-mail, mobile or address is availble.
I want to write a LINQ query to give me an count of trues for each column, so how many rows in the e-mail column are set to true (and the same for the other two columns)
If you need a single object containing the results:
var result = new {
HasEmailCount = list.Count(x => x.HasEmail),
HasMobileCount = list.Count(x => x.HasMobile),
HasAddressCount = list.Count(x => x.HasAddress)
};
Or using the aggregate function:
class Result
{
public int HasEmail;
public int HasAddress;
public int HasMobile;
}
var x = data.Aggregate(
new Result(),
(res, next) => {
res.HasEmail += (next.HasEmail ? 0 : 1);
res.HasAddress += (next.HasAddress ? 0 : 1);
res.HasMobile += (next.HasMobile ? 0 : 1);
return res;
}
);
x is of Type Result and contains the aggregated information. This can also be used for more compelx aggregations.
var mobileCount = myTable.Count(user => user.MobileAvailable);
And so on for the other counts.
You can do it like so:
var emailCount = yourDataContext.YourTable.Count(r => r.HasEmail);
etc.