How to return a query from cosmos db order by date string? - linq

I have a cosmos db collection. I need to query all documents and return them in order of creation date. Creation date is a defined field but for historical reason it is in string format as MM/dd/yyyy. For example: 02/09/2019. If I just order by this string, the result is chaos.
I am using linq lambda to write my query in webapi. I have tried to parse the string and try to convert the string. Both returned "method not supported".
Here is my query:
var query = Client.CreateDocumentQuery<MyModel>(CollectionLink)
.Where(f => f.ModelType == typeof(MyModel).Name.ToLower() && f.Language == getMyModelsRequestModel.Language )
.OrderByDescending(f => f.CreationDate)
.AsDocumentQuery();
Appreciate for any advice. Thanks. It will be huge effort to go back and modify the format of the field (which affects many other things). I wish to avoid it if possible.

Chen Wang.Since the order by does not support derived values or sub query(link),so you need to sort the derived values by yourself i think.
You could construct the MM/dd/yyyy to yyyymmdd by UDF in cosmos db.
udf:
function getValue(datetime){
return datetime.substring(6,10)+datetime.substring(0,2)+datetime.substring(3,5);
}
sql:
SELECT udf.getValue(c.time) as time from c
Then you could sort the array by property value of class in c# code.Please follow this case:How to sort an array containing class objects by a property value of a class instance?

Related

Count maching date data [duplicate]

I need to call ToShortDateString in a linq query suing lambda expressions:
toRet.Notification = Repositories
.portalDb.portal_notifications.OrderByDescending(p => p.id)
.FirstOrDefault(p => p.date.ToShortDateString() == shortDateString);
but I get the error:
An exception of type 'System.NotSupportedException' occurred in
System.Data.Entity.dll but was not handled in user code
Additional information: LINQ to Entities does not recognize the method
'System.String ToShortDateString()' method, and this method cannot be
translated into a store expression.
What can I do, considering that I do need to use ToShortDateString() ?
Thanks.
Linq to Entities cannot convert ToSortDateString method into SQL code. You can't call it on server side. Either move filtering to client side (that will transfer all data from server to client), or consider to use server-side functions to take date part of date (you should pass DateTime object instead of shortDateString):
EntityFunctions.TruncateTime(p.date) == dateWithoutTime
You shouldn't be forcing a string comparison when what you're working with is Date/time data - as soon as you force string comparisons, you're suddenly having to deal with how the strings are formatted.
Instead, have something like:
var endDate = targetDate.AddDays(1);
toRet.Notification = Repositories
.portalDb.portal_notifications.OrderByDescending(p => p.id)
.FirstOrDefault(p => p.date >= targetDate && p.date < endDate);
(Assuming that targetDate is whatever DateTime variable you had that was used to produce shortDateString in your code, and is already a DateTime with no time value)
Try this,
You can also used with below code.
Activity = String.Format("{0} {1}", String.Format("{0:dd-MMM-yyyy}", s.SLIDESHEETDATE), String.Format("{0:HH:mm}", s.ENDDATETIME))
ToShortDateString() method usually used to work only with date and ignore time stamps.
You will get exactly today result-set by using the following query.
Repositories.portalDb.portal_notifications.OrderByDescending(p => p.id)
.FirstOrDefault(p => p.date.Date == DateTime.Now.Date);
By using Date property of DateTime struct you can just fetch record of that date only.
Note: Linq to Objects. Only works if you CAN (or have option) to bypass ToShortDateString() method

Filter records using Linq on an Enum type

I'm hoping this is a simple solution. I have a field (PressType) in a table (Stocks) that is seed populated by using an Enum. The table stores the data as an integer. However when I want to query some data via Linq it gives me issues. I can filter any other fields in the table using this format however on the Enum populated field it says
the "==" operator cannot be applied to operands of type "Models.PressType" and "string".
Any help you could give would be appreciated, thanks.
var test = db.Stocks.Where(x => x.PressType == myValue);
There is nothing wrong with your Linq. Your problem is that myValue is of type string. You need to convert your string to the enum first.
string myValue = SomeControl.Text;
Models.PressType myValueAsEnum = (Models.PressType)
Enum.Parse(typeof(Models.PressType), myValue);
IQueryable<Stock> test = db.Stocks.Where(x => x.PressType == myValueAsEnum);

Extracting timestamp field in Oracle vs MySQL from Grails-Groovy

I am using grails/groovy, and from my controller I am currently doing this for retrieving field from Mysql table containing datetime field
SimpleDateFormat Sformat = new SimpleDateFormat("yyyy-MM-dd");
String format_datenow = Sformat.format(new Date());
String format_dateprevious = Sformat.format(new Date() -31);
String markerCalcQuery =
"select sum(trans_cnt) as t_cnt, location from map2_data where fdate between '"+format_dateprevious+"' and '"+format_dateprevious+"' and res_id = "+res_id+" group by map2_data.location";
res_row=gurculsql.rows(markerCalcQuery);
The above query fails on Oracle11g with error
ORA-01843: not a valid month.
The error I feel is because MySQL stores date in this format: 2011-12-28 02:58:26 and Oracle stores date like this: 28-DEC-11 02.58.26.455000000 PM
How do I make the code generalised, one way is to make the database in Oracle store the date in the same format which I am thinking the way to handle this rather than from the code. If yes, how to change date format in the Oracle db?
Can I specify the format in the grails domain class for map2_data so that no matter what database it is we will have the datetime in the same format.
For several reasons (one being to code database independent - which is basically what you'd need ;-)), it is better to avoid creating SQL statements in your code. Try to use the Grails criteria DSL, e.g. something like
def criteria = YourDomainObject.createCriteria()
criteria.get {
between ('fdate', new Date()-31, new Date())
projections {
sum('trans_cnt')
groupProperty('location')
}
}
(ontested, but should help you get started).
If for some reason you can't use the criteria API, try the fallback to HQL (Hibernate Query Language). I'd always try to avoid to write plain SQL.
In Oracle, dates have their own type, they aren't strings. If you have a string, you should convert it to a date using the TO_DATE function.
String format_datenow = "TO_DATE('" + Sformat.format(new Date()) + "', 'YYYY-MM-DD')";
To make it work also in MySQL, you can create a stored function named TO_DATE that just returns its first argument.

Dynamic Linq - no property or field exists in type 'datarow'

I am using Northwind Customers Table where I fill the dataset and get the datatable.
I am trying to use dynamic linq and want to select columnName dynamically
var qry = MyDataTable.AsEnumerable().AsQueryable().Select("new(Country)");
Right now I have hard coded country but even then I get this error
No property or field 'Country' exists in type 'datarow'
I would like to eventually change this query to take the column name dynamically.
Please help!!! thanks.
The important hint is here (in bold):
No property or field 'Country' exists
in type 'datarow'
The extension method AsEnumerable of the DataTable class returns an IEnumerable<T> where T has the type DataRow. Now the Select method of Dynamic LINQ wants to work with this type DataRow which hasn't a property Country of course.
You could try this instead:
var qry = MyDataTable.AsEnumerable().AsQueryable()
.Select("new(it[\"Country\"] as CountryAlias)");
it now represents a variable of type DataRow and you can use methods of this type and perhaps also the indexer in my example above. (Dynamic LINQ supports accessing array elements by an integer index, but I am not sure though if accessing an indexer with a string key will work.)
I've used Slauma's answer and it worked. In addition i was doing OrderBy with dynamic linq maybe this will help to someone. I'll just drop the code here.
string dynamicLinqText = $"it[\"{sortColumnName}\"] {sortDirection}"; //it["PERSON_NAME"] asc
result = result.AsEnumerable().OrderBy(dynamicLinqText).CopyToDataTable();

LINQ Convert string to datetime

In SQL I do it like this:
DateMonth=convert(datetime, convert(char(6), AASI.Inv_Acctcur) + '01')
How to do it in LINQ? String is in following format:
"yyyyMMdd"
Thanks,
Ile
EDIT:
Example of SQL usage:
SELECT convert(datetime, '20161023', 112) -- yyyymmdd
Found here: http://www.sqlusa.com/bestpractices/datetimeconversion/
This page on MSDN documentation lists all convert methods that LINQ to SQL does not support.
Convert.ToDateTime is not listed in there. So, I guess you could just use Convert.ToDateTime to do what you want.
This is not something typically for LINQ or any LINQ over Expression trees enabled provider (such as LINQ to SQL, LINQ to Entities, LINQ to NHibernate, LLBLGen Pro, etc, etc). This is simply a language question. You want to know how to convert the format yyyyMMdd to a DateTime.
The trick is to leave the conversion OUT of your LINQ (over Expression trees) query, because a LINQ provider will not be able to convert it, or if it can, you will get very provider specific implementation.
Therefore, the trick is to get it out of the database as a string (or of course even better: change your database model) and convert it to a DateTime in .NET. For instance:
// Doing .ToArray is essential, to ensure that the
// query is executed right away.
string[] inMemoryCollectionStrings = (
from item in db.Items
where some_condition
select item.Inv_Acctcur).ToArray();
// This next query does the translation from string to DateTime.
IEnumerable<DateTime> dates =
from value in inMemoryCollectionStrings
select DateTime.ParseExact(value, "yyyyMMdd",
CultureInfo.InvariantCulture);
In other words, you can use the following line to make the conversion:
DateTime.ParseExact(value, "yyyyMMdd", CultureInfo.InvariantCulture);

Resources