Cosmos DB read call - c#

I'm making a call to Azure Cosmos DB where I know the data I'm querying does NOT exist.
I was expecting to get a null value but instead I'm getting:
Enumeration yielded no results
How do I test whether I received a value or not? I was testing for null which doesn't work because the outcome is not null.
My code looks something like this:
var result = await _client.ReadQuery<myObject>(AccountsCollection, sql, pa);
if(result == null)
return null;

Instead of just checking on result == null you should use the LINQ extension method .Any() to see if there are any items that match a condition (in your case the condition is just anything existing in the collection):
if(result == null || !result.Any())
{
return null;
}

Related

Best practice to check for null in LINQ query

Assuming I have a LINQ query as such ...
var selectedUser = myDb.Users.Where<User>(u => u.Email == email).Single<User>();
What is the best way to see if I received a result back? Do I just check if selectedUser != null
if (selectedUser != null)
{
// OK, not null so go ahead and do stuff
}
Single() will throw an exception if there are no matches.
SingleOrDefault() will return a single element, or a default value. However it will throw exception if there are more than one element in the sequence.
If you are ok with just taking the first element if there happens to be more than use FirstOrDefault() for this:
var selectedUser = myDb.Users.FirstOrDefault(u => u.Email == email);
Then just check if it is null like normal:
if (selectedUser != null)
{
// OK, not null so go ahead and do stuff
}
Side Note In either case you shouldn't need your explicit <T> definitions. Also the Where() clause is redundant, you can pass your lambda in FirstOrDefault(), Single(), SingleOrDefault(), etc.
.Single will throw an exception if there isn't a matching item. Instead use SingleOrDefault and check for null.

Avoid NullReferenceException in LINQ Expression on Datatable column

I am stuck with null values in my Datatable "articles". Using LINQ to get a list of articles works for column ArticleId but with column "ArticleVariations" the null values are killing me.
var result = this.articles.AsEnumerable().Where(r =>r.Field<String>("ArticleId").Equals(artNo)); // works. no nulls there ;)
var result = this.articles.AsEnumerable().Where(r =>r.Field<String>("ArticleVariations").Equals(artNo)); // stuck with nulls here
If the column contains nulls, I get an NullReferenceException, Can I avoid this somehow and is it possible to merge both expressions?
You can use null-conditional and null-coalescing operators:
var result = this.articles.AsEnumerable()
.Where(r =>r.Field<String>("ArticleVariations")?.Equals(artNo) ?? false);
The problem obviously occurs because r.Field<String>("ArticleVariations") retuns null. Thus you have to check for null before calling Equals on it.
For that you can call multiple statements within a LINQ-expression:
var result = this.articles.AsEnumerable().Where(r => {
var res = r.Field<String>("ArticleVariations");
if (res != null) return res.Equals(artNo);
else return false;
});
If the field can be null then just reverse your test:
var result = this.articles.AsEnumerable().Where(r => artNo.Equals(r.Field<String>("ArticleVariations")));
Then all you need to do is check that artNo is not null before making the call:
List<Type> result;
if (string.IsNullOrWhiteSpace(artNo))
{
result = new List<Type>();
}
else
{
result = this.articles.... as before
}
Where just takes a function which returns a bool to determine if it should filter an item out of a collection. You can write it with a multi-statement body just like any other function to make nulls easier to deal with. Something like this should be a good starting point:
.Where(r => {
string articleVariations = r.Field<string>("ArticleVariations");
return articleVariations != null && articleVariations.Equals(artNo);
});
IF you want to combine those checks somehow to build a list where one or the other of the given fields matches your artNo, you can just add it to the function body.
If the column contains nulls, I get an NullReferenceException, Can I avoid this somehow
Avoid using instance Equals methods where possible. Use the respective operators or static Equals methods because they handle correctly nulls for you.
In your concrete case, the easiest way is to replace Equals with ==:
var result = this.articles.AsEnumerable()
.Where(r => r.Field<string>("ArticleId") == artNo);
var result = this.articles.AsEnumerable()
.Where(r => r.Field<string>("ArticleVariations") == artNo);
and is it possible to merge both expressions?
It depends on what do you mean by "merging" them. If you mean matching article or variation by the passed artNo, then you can use something like this
var result = this.articles.AsEnumerable()
.Where(r => r.Field<string>("ArticleId") == artNo
|| r => r.Field<string>("ArticleVariations") == artNo);

Why is IEnumerable<object> not null after LINQ query?

I have a List which holds > 10.000 items. I am doing a LINQ query on this
IEnumerable<Term> terms = from t in regionCollection
where t.Name == strRegion
select t;
if (terms != null)
{
m.RegId = Convert.ToInt32(terms.FirstOrDefault().CustomProperties["dbId"]);
}
If (terms !=null) is always not null! I have a feeling that the query is executed only if i try to access the single object inside the IEnumarable. Is this correct and if yes how can i check if my IEnumarable is not null?
Variable term will always have a value, it will never be null, because if query returns no results then terms will be empty enumerable. In your case you can update the code like this:
// Get first item of query or default value
var firstTerm = terms.FirstOrDefault();
// If there were no items, then firstTerm is null
if (firstTerm != null)
{
// This code block is only executed if the query had at least 1 item in results
m.RegId = Convert.ToInt32(firstTerm.CustomProperties["dbId"]);
}

Why does EF not return any results when comparing null variable?

I'm having an issue selecting data in my data context in Entity Framework and I've narrowed it down to querying for null values. I have a method like this:
public void DoStuff(int? someInt)
{
var someData = dataContext.MyEntities.Where(x => x.SomeProperty == someInt);
// someData always yields no results if someInt is null, even though
// there are rows in the table that have null for that column.
}
The above method fails if someInt is null. But this line works:
var someData = dataContext.MyEntities.Where(x => x.SomeProperty == null);
Why do I get data in the second one but not the first one?
I guess, then, that it is generating and using a SQL query of the form that expects a non-null value:
where x.SomeProperty = #param
Instead of the SQL to show the c# null-equality semantic:
where x.SomeProperty is null
(the key point here being that in c#, null equals null; in ANSI-SQL, null neither equals null nor (confusingly) not-equals null - different syntax is need to test nulls)
I've seen LINQ-to-SQL do the same thing, and agree that it is counter-intuitive. The only suggestion I have is: test the candidate parameter for null yourself and do the constant/literal == null test instead. It would also probably be able to do the same by inspecting and expression tree and re-writing it, if you are into expression trees - but special-casing the null is simpler.
someInt isn't null on its own. someInt.Value would be null.

linq where clause and count result in null exception

The code below works unless p.School.SchoolName turns out to be null, in which case it results in a NullReferenceException.
if (ExistingUsers.Where(p => p.StudentID == item.StaffID &&
p.School.SchoolName == item.SchoolID).Count() > 0)
{
// Do stuff.
}
ExistingUsers is a list of users:
public List<User> ExistingUsers;
Here is the relevant portion of the stacktrace:
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Linq.Enumerable.WhereListIterator1.MoveNext()
at System.Linq.Enumerable.Count[TSource](IEnumerable1 source)
How should I handle this where clause?
Thanks very much in advance.
I suspect p.School is null, not SchoolName. Simply add a null check before accessing SchoolName. Also, use Any() to check if there are any results instead of Count() > 0 unless you're really in need of the count. This performs better since not all items are iterated if any exist.
var result = ExistingUsers.Where(p => p.StudentID == item.StaffID
&& p.School != null
&& p.School.SchoolName == item.SchoolID)
.Any();
if (result) { /* do something */ }
For all database nullable columns, we should either add null check or do simple comparision a == b instead of a.ToLower() == b.ToLower() or similar string operations.
My observation as below:
As they get iterated through Enumerable of LINQ Query for comparision against with input string/value, any null value (of database column) and operations on it would raise exception, but Enumerable becomes NULL, though query is not null.
In the case where you want to get the null value (all the student, with school or not) Use left join.
There are a good example on MSDN
If I remember correctly (not at my developer PC at the moment and can't check with Reflector), using the == operator results in calling the instance implementation string.Equals(string), not the static implementation String.Equals(string, string).
Assuming that your problem is due to SchoolName being null, as you suggest, try this:
if (ExistingUsers.Where(
p => p.StudentID == item.StaffID
&& String.Equals( p.School.SchoolName, item.SchoolID)).Count() > 0)
{
// Do stuff.
}
Of course, comments by other answers count as well:
Using Any() instead of Count() > 0 will generally perform better
If p.School is the null, you'll need an extra check
Hope this helps.

Categories

Resources