When the DB Table is empty my request to access the result throws an error.
var resultEthnie = (from k in db.N_QONV
where k.qonv_fk_numvol == clientId &&
k.qonv_fk_eon_id == 64
select new { k.qonv_fk_num_question }
).Take(1);
return Convert.ToInt32(resultEthnie.FirstOrDefault().qonv_fk_num_question);
Is there a way to have a default return result value when the query result is empty?
Is there a way to have a default return result value when the query result is empty?
You are getting the error because you try to access the first element of the query result without check if it is empty or not.
To fix the issue use ? operator after the FirstOrDefault() method:
resultEthnie.FirstOrDefault()?.qonv_fk_num_question; // ? will escape accessing to
// qonv_fk_num_question if the result is null
However here I see a bit more elegant solution. Instead of using filtering, select and later trying to access the first element of the result, simple use FirstOrDefault() method lambda version:
var result = db.N_QONV.FirstOrDefault(k => (k.qonv_fk_numvol == clientId) &&
(k.qonv_fk_eon_id == 64));
return Convert.ToInt32(result?.qonv_fk_num_question);
Related
I am using Visual Studio 2012 with MySQL 5.7 Community Edition. I am getting object reference not set to an instance of object on the below query.
var oList = (
from dm in dbContext.document_master
join um in dbContext.user_master on dm.Alocated_CAA equals um.UserId
where (dm.DocumentHandle != null)
select new TaskLogReport
{
documentDate = dm.Document_Date,
documentHandle = dm.DocumentHandle,
fileNumber = dm.FileNumber,
statusRemarks = dbContext.statushistories
.Where(x => x.DocumentHandle == 12345678).FirstOrDefault().Remarks
}).ToList();
In the above query If I get change 12345678 to dm.DocumentHandle, then getting object reference not set to an instance object.
Try with MS-SQL server , working fine.
You get the error because FirstOrDefault() returns null, because there are no objects who's DocumentHandle equals dm.DocumentHandle. Changing dm.DocumentHandle to 12345678 works because there is one matching element.
This line is the problem:
.Where(x => x.DocumentHandle == 12345678).FirstOrDefault().Remarks
C#'s Enumerable.FirstOrDefault() method returns either the first matching element of an enumerable, or, if there aren't any, the default value of the type. In the case of nullable types, FirstOrDefault() returns null if no elements are found.
The reason you get no error when you use 12345678 is because there is at least one matching value with that DocumentHandle. However, when you change that to dm.DocumentHandle, no matching elements are found, causing FirstOrDefault to return null. Then you essentially do null.Remarks, which causes the error.
You should change your code to this:
.FirstOrDefault(x => x.DocumentHandle == dm.DocumentHandle)?.Remarks
There are two differences here:
Got rid of the where and moved the predicate to the FirstOrDefault call. This is just a cleaner way of doing what you were doing before.
Added the ? at the end of the FirstOrDefault call. That is the null propagation operator.
What it does is it turns this:
int foo;
if (bar != null)
{
foo = bar.foo;
}
Into this:
int foo = bar?.foo;
Now, if there are matching elements, statusRemarks will be equal to the first one's Remarks. Otherwise, statusRemarks will be null.
EDIT: The null propagation operator was implemented in C# 6.0, which is .Net 4.6 onwards, so it won't work in .Net 4.0.
You'll have to modify your query and implement a check, like so:
var oList = (
from dm in dbContext.document_master
join um in dbContext.user_master on dm.Alocated_CAA equals um.UserId
where (dm.DocumentHandle != null && dbContext.statushistories.Count(x => x.DocumentHandle == dm.DocumentHandle) > 0)
select new TaskLogReport
{
documentDate = dm.Document_Date,
documentHandle = dm.DocumentHandle,
fileNumber = dm.FileNumber,
statusRemarks = dbContext.statushistories.First(x.DocumentHandle == dm.DocumentHandle).Remarks
}).ToList();
The action method in the controller receive a value, like a couple of letters. The code checks if the table contains any of this letters. I'm using this code for that task:
var result = db.People.Where(b => b.Name.ToUpper().Contains(filter.ToUpper()));
But how can I check if the result variable is empty or null, when there are not any matching letters? I tested this, but it's not working!
If(result == ""){
// Do something
}
I would like to use Viewbag to send a message that there was no match or perhaps do this check in the View. I'm using this with some AJAX and Partial Views and it's working perfect, but I just want show a message if there are not any matches. What is the best way to check if the result value is empty or null?
The simplest way would be by using !result.Any():
var result = db.People.Where(b => b.Name.ToUpper().Contains(filter.ToUpper()));
If(!result.Any()){
// Do something
}
From MSDN on IEnumerable:
Any()
Determines whether a sequence contains any elements.
Fits exactly what you need.
Try this, Using FirstOrDefault it will give you the first record from the result, else if no result is yielded from the query it returns default value that is null,
var result = db.People.Where(b => b.Name.ToUpper().Contains(filter.ToUpper())).FirstOrDefault();
If(result == null){
// Do something
}
Or if you want to use this result, to manipulate something in your code then you can use the ToList(). It will return you list of values and if the query didnt yield anything then the list count will be 0.
var result = db.People.Where(b => b.Name.ToUpper().Contains(filter.ToUpper())).ToList();
If(result.Count == 0){
// Do something
}
Your code is not working because the code is returning an object not a string if you want to return a string then you have to use the "Select" clause to select a specific field and if you want to check in the same code then modify :
var result = db.People.Where(b => b.Name.ToUpper().Contains(filter.ToUpper())).ToList();
if(result != null && result.Count > 0)
it will work for you.
For IEnumerable we can use Any(), your code will can be written as
if(!db.People.Where(b => b.Name.ToUpper().Contains(filter.ToUpper())).Any() {
// do some thing
}
I'm new the the LINQ to XML world. I'm attempting to retrieve the value of Identity but only when the domain attribute of Credential is "NetworkID". Here's the code I'm testing with:
XML Snippet:
<Sender>
<Credential domain="NetworkID">
<Identity>MyIdentity</Identity>
<SharedSecret>MySharedSecret</SharedSecret>
</Credential>
<UserAgent>MyUserAgent</UserAgent>
</Sender>
C#:
var credential = xdoc.Descendants("Sender")
.Elements("Credential")
.Where(x => x.Attribute("domain").Value == "NetworkID").FirstOrDefault()
.Descendants("Identity").FirstOrDefault();
Question:
Obviously, if the Credential node is not found, the LINQ query will generate an error because I'm calling .Descendants() on null.
Is it possible to write the query so that it return Identity or null if either element is not found?
Just remove FirstOrDefault() after the Where():
var credential = xdoc.Descendants("Sender")
.Elements("Credential")
.Where(x => x.Attribute("domain").Value == "NetworkID")
.Descendants("Identity")
.FirstOrDefault();
Where() returns empty result set and FirstOrDefault() on empty result set returns null this is why .Where().FirstOrDefault().Descendants() caused null reference exception.
If you use
var identity =
xdoc.Descendants("Sender")
.Elements("Credential")
.Where(x => (string)x.Attribute("domain") == "NetworkID")
.Descendants("Identity")
.FirstOrDefault();
you should get what you want. Or you need to break the code up, doing one FirstOrDefault() in the first part e.g.
var credential = xdoc.Descendants("Sender").Elements("Credential").FirstOrDefault(c => (string)c.Attribute("domain") == "NetworkID");
var identity = credential != null ? credential.Element("Identity") : null;
My DBML exposes a record set that has a nullable nvarchar field. This nullable nvarchar field is represented as a string in my C# code.
Sometimes this field is null, sometimes it is an empty string, and sometimes it actually has a value.
Does String.IsNullOrEmpty() work in LINQ To SQL? For instance, would the following work:
var results = from result in context.Records
where String.IsNullOrEmpty(result.Info) == false
select result;
Curiously, per MSDN String.IsNullOrEmpty is supported (by virtue of it not being unsupported), yet I can only find complaints about it not being supported.
However, if it does work you should not explicitly compare it to a boolean value, instead:
var results = from result in context.Records
/*XXX broke :( where !String.IsNullOrEmpty(result.Info) */
where !(result.Info == null || result.Info.Equals(""))
select result;
I don't know if that works, but I'm sure this does:
where (result.Info ?? "") != ""
(strongly recommend the parens, query generator can get confused without them)
It is not supported since attempting to use it results in a NotSupportedException being thrown with this message:
Method 'Boolean IsNullOrEmpty(System.String)' has no supported
translation to SQL.
Instead, you can use this approach to do the same thing:
var results = from result in context.Records
where result.Info != null && result.Info.Length > 0
select result;
You may also use result.Info != String.Empty instead of checking the length. Both approaches will work.
I had problems with all answers except for #ahmad-mageed's answer.
Ended up using a more concise syntax of:
where (result.Info ?? "").Length > 0
Or
result => (result.Info ?? "").Length > 0
You can use a function as argument to the Where method if you use a Linq query, e.g.
var results = context.Records.Where(string.IsNullOrEmpty);
But in this case that would give you all null or empty elements, instead of the opposite. Then create an extension method to the string class (e.g. string.IsNotNullOrEmpty) or do something like this:
var results = context.Records.Except(context.Records.Where(string.IsNullOrEmpty));
I have two queries which return a collection of the same kind of object, after these two queries are done, I want to union them.
var results = from t in All()
where t.Blah.Contains(blahblah)
select t;
var results2 = from t in All()
where t.blah2.contains(blahblah)
select t;
return results.Union(results2);
It is possible that the second query could return no results, and be null.
It seems like if I try and perform a union with the two, if the second argument is null it will throw an ArgumentNullException.
The obvious answer would be to just to perform .ToList() on the second query to see if it contains anything. The problem with this is I am trying to take advantage of deferred execution and dont want to actually perform the query on the database at this stage.
Is there any way around this?
Edit - Solution
var results2 = from t in All()
where t.blah2!=null && t.blah2.Contains(blahblah)
select t;
Basically, the actual query was returning null as I was trying to do a contains on a null list
Thanks for the help!
results2 should return an empty list and not null when executing its query. The code you have should not cause any problems and should work just fine in all cases simple cases I can think of. Can you provide input which would cause the problem you are trying to solve?
Would the following not solve your problem?
return from t in All()
where t.Blah.Contains(blahblah) && t.Blah2.Contains(blahblah)
select t;
However, if results and results2 need to remain separate and you want to combine them:
return results.Union(results2 ?? Enumerable.Empty<TResult>());
var results = from t in All()
where t.Blah.Contains(blahblah)
select t;
var results2 = from t in All()
where t.blah2.contains(blahblah)
select t;
return (results2 != null || results2.Count() > 0) ? results.Union(results2) : results;
This will either return the union if there is something in results2, or just return the first result set.