Check for null value in LINQ before performing operation on it - linq

I am using the SharePoint 2010 REST services to extract information from an SP list. One of the conditions is that if a date exists in a record, and the year of that date is this year, then include it. Otherwise, don't.
What I'm concerned about is that I have to use a date cast method on the date field, and if that field is null then the code will fail. Is there any way to check if the value is null BEFORE using the cast?
My current code is here:
Dim results As List(Of CurrentProjectsItem) =
(From items In service.CurrentProjects
Where (items.StatusValue = "Closed" Or CDate(items.DateClosed).Year = Now.Year))
Order By items.Priority
Select items).ToList()
Any help would be appreciated, I don't use LINQ all that often!

You can include that check in your condition. So this:
CDate(items.DateClosed).Year = Now.Year
logically becomes this:
((items.DateClosed Is Not Nothing) And (CDate(items.DateClosed).Year = Now.Year))
(Though I'm curious what type DateClosed is in the first place, if not a Date?)
Edit:
The DateClosed is Date?
In that case it's a Nullable(Of Date) object, which has properties on it for checking this:
((items.DateClosed.HasValue) And (items.DateClosed.Value.Year = Now.Year))
No need for casting.

Related

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

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?

Extract only date part in a datetimein LINQ

We have some data in a DataTable and we are using the query like this to get what we need.
IEnumerable<Results> subResult = from query in datatable.AsEnumerable()
select new Results
{
Name = query.Field<string>("Name"),
Date = query.Field<DateTime?>("Date")
}
This above query returns what i need but date in full format (Ex: m/dd/yyyy hh:min:sec am/pm) but we need only date part of it(only mm/dd/yyyy need to be pulled in). When looked in the properties of this, couldn't find an implicit way to get it, please help me in getting this result. Thanks.
The DateTime class has all the properties you just mentioned. You should try to fix your display with the ToString("anyformatyouwant") formats.
What about this?
Date = query.Field<DateTime?>("Date").Date
This will give you just the date part:
IEnumerable<Results> sub-result= from query in datatable.AsEnumerable()
where new Results
{
Name = query.Field<string>("Name"),
Date = query.Field<DateTime?>("Date").Date
}
However if you just want to display the date somewhere (meaning you're not using this to do date grouping, etc. then I would just specify the display format in your UI layer.
AFAIK there is no Date Class in .net, if you want pure date you should write a Class for that, otherwise you can pull out the part as a string
DateTime.Now.Date.ToString("yyyy/MM/dd")
gives you the current date in string type, but if you get the .Date part it gives you a DateTime object which still has a time part showing AM 12:00:00:0 blah blah

LINQ 2 Entities-query is not working, but why?

everyone! ))
Here is code.
var existingEntities = (from record in globalOne.serviceContext.records_out
where record.timestamp.Date == DateTime.Now.Date
select record ).ToList();
It doesn't work.
Another code:
var existingEntities = (from record in globalOne.serviceContext.records_out
where record.timestamp.Day == DateTime.Now.Day
select record ).ToList();
It does work.
So, problem id in next string:
where record.timestamp.**Date** == DateTime.Now.Date
also won't do
where record.timestamp.Date.Equals(DateTime.Now.Date)
But why? I have no clue. "Timestamp" field is dateTime field in MS SQL SERVER.
And - there is NO records in table.
And I almost forgot - what does it mean - "doesn't work".
App just will not reach the breakpoint after that query(first), without any error, without anything.
Thanks.
You can call record.timestamp.Date because EF can't convert it to required expression tree (then convert it to sql command). In fact EF supports limited number of functions and properties, But for DateTime, EF has some good Canonical functions. You can use them in your case, e.g you can use Day(),Month(),Year() functions to solve your problem (see the link).

How do I return multiple xml elements/ attributes with linq, and create objects with them?

I'm working with an xml document in C# that has multiple (100+) points of stock market data. I'd like to create objects and add them to a List<> by passing initialization values retrieved from an xml document via linq. At the moment I'm just able to run a linq query and return one of the xml fields, in the code below, the attribute "symbol." I'd also like to return the document's "LastTradeDate, DaysLow, DaysHigh, LastTradePriceOnly, Open, and Volume." From there, my custom constructor is: StockDataPoint(Symbol, TradeDate, Open, High, Low, Close, Volume). A nudge in the right direction would be great. Here's the current linq:
var makeInfo =
from s in doc.Descendants("quote")
where s.Element("LastTradeDate") != null
&& s.Attribute("symbol") != null
let dateStr = s.Element("LastTradeDate").Value
where !string.IsNullOrEmpty(dateStr)
&& DateTime.Parse(dateStr, enUS) == targetDate
select s.Attribute("symbol").Value;
Well it depends on your XML format, but you might just want something like:
...
select new StockDataPoint((string) s.Attribute("symbol"),
(DateTime) s.Attribute("TradeDate"),
(decimal) s.Attribute("Open"),
(decimal) s.Attribute("High"),
(decimal) s.Attribute("Low"),
(decimal) s.Attribute("Close"),
(long) s.Attribute("Volume"));
Note that by use the explicit operators on XAttribute, you can avoid performing the parse yourself. Indeed, you can use this earlier in your query too:
var makeInfo = from s in doc.Descendants("quote")
where s.Attribute("symbol") &&
(DateTime?) s.Attribute("LastTradeDate") == targetDate
select ...
If the target of the cast is a nullable type (either a nullable value type or a reference type) then if the attribute is missing, the result will be the null value for that type, which is very handy.
You need to create a class:
select new YourClass {
Symbol = s.Attribute("symbol").Value,
...
}

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();

Resources