Any knows a quickest Ternary operation for this.
label1.Text = Cclass.TestMe()
.Where(t => t.GFName == (textBox1.Text == ""
? "GName"
: textBox1.Text))
.First()
.GFName == null ?
"Nothing" :
"Super";
I was trying to check if the List is empty return something. So the compiler will not throw a Exception or unhanded error.
The reason of this exception is First(). It will throw an exception if there's no row to be returned. Instead of that you can use FirstOrDefault() which will return the default value (NULL for all reference types) instead. But if you want to check if there any element inside your list which mathcing the condition, then you must use Any() extension method:
return Cclass.TestMe()
.Any(t => t.GFName == (textBox1.Text == "" ? "GName" : textBox1.Text)) ?
"Super" :
"Nothing";
By the way, it would be better to set text outside of your query:
var filteredText = textBox1.Text == "" ? "GName" : textBox1.Text;
return Cclass.TestMe().Any(t => t.GFName == filteredText) ?
"Super" :
"Nothing";
If I understand you right you want to return one value if the where clause returns something and another if not. That would be:
label1.Text = Cclass.TestMe()
.Any(t => t.GFName == (textBox1.Text == ""
? "GName"
: textBox1.Text)) ?
"Super" :
"Nothing";
If that's not what you want, then rearrange your code to use if statements to make it work, then make it better. Ugly working code is always better than elegant broken code.
Related
I am working on c# data model class, I created instance and assigning values from another object. I am aware of single line comparision but I need multiple, I have tried && operator but compiler complain 'invalid opperator'. I am sure what I am missing, surly it must be simple!
var answerDataModel = new AnswerDataModel()
{
Id = answerId,
//need help to
Value = AnswerDtoObject.Answers.FirstOrDefault() == null? &&
isSubQuestionExist == true ? "_SBQA"
: AnswerDtoObject.Answers.FirstOrDefault(),
};
if I remove "&& isSubQuestionExist == true ?", then code works
You have an errant ? operator. Just combine your comparisons in a single conditional operator:
Value = (AnswerDtoObject.Answers.FirstOrDefault() == null && isSubQuestionExist == true) ?
"_SBQA" :
AnswerDtoObject.Answers.FirstOrDefault()
Value = (AnswerDtoObject.Answers.FirstOrDefault() == null) &&
(isSubQuestionExist == true) ? "_SBQA"
: AnswerDtoObject.Answers.FirstOrDefault(),
I want to create an if/else statement in this case :
var controls= _listControls
.Select(
control => new
{
Name,
Quantity,
Valid = isValid
? sp.GetInfos(ID).SerialNumber.ToString()
: string.Empty
})
.ToList();
I just want to check if sp.GetInfos(ID).SerialNumber.ToString()is null in the statement and say if it's not null ? DoThings() : DoThings() .
Thanks
You can use ternary operators inside other ternary statements like this
Valid = isValid
? string.IsNullOrEmpty(sp.GetInfos(ID).SerialNumber?.ToString())
? string.Empty
: sp.GetInfos(ID).SerialNumber.ToString()
: string.Empty
N.B. The SerialNumber?.ToString() is a null conditional operator, you can read more about it here
You can encapsulate all logic in a helper method. As I consider it's more readable and also you are able to test this method separately.
string Valid(....)
{
if (isValid)
{
if (sp.GetInfos(ID).SerialNumber == null)
{
....
}
else
{
..
}
}
return string.Empty;
}
And then simply call this method inside LINQ query
var controls = _listControls
.Select(
control => new
{
Name,
Quantity,
Valid = Valid (...)
})
.ToList();
First, Thomas Levesque had a good solution for ordering fields in a related table where the relation may not always be there:
userQuery = userQuery.OrderBy(u =>
(u.Department != null) ? u.Department.Name : String.Empty);
I need to do the same thing. My aggregate root is enormous:
myQuery = myQuery.OrderBy(p =>
(p.Seconds == null
? 0
: p.Seconds.FirstOrDefault() == null
? 0
: p.Seconds.First().Thirds == null
? 0
: p.Seconds.First().Thirds.FirstOrDefault() == null
? 0
: p.Seconds.First().Thirds.First().Forths == null
? 0
: p.Seconds.First().Thirds.First().Forths.FirstOrDefault() == null
? 0
: p.Seconds.First().Thirds.First().Forths.First().myField));
Is this really the way to do this, or is there something much easier to read? My other problem is that the nested myField has a matching "default" value sitting in the top level Query, also named by myField. The idea was to Order by the coalesce of these two fields (??).
Edit: I think this would include the "default value" from the first field:
myQuery = myQuery.OrderBy(p =>
(p.Seconds == null
? p.myDefaultField // Used to be zero
: p.Seconds.FirstOrDefault() == null
? p.myDefaultField
: p.Seconds.First().Thirds == null
? p.myDefaultField
: p.Seconds.First().Thirds.FirstOrDefault() == null
? p.myDefaultField
: p.Seconds.First().Thirds.First().Forths == null
? p.myDefaultField
: p.Seconds.First().Thirds.First().Forths.FirstOrDefault() == null
? p.myDefaultField
: p.Seconds.First().Thirds.First().Forths.First().myField));
How could I rewrite this OrderBy to be cleaner? This code fails with an error of "Cannot compare elements of type 'System.Collections.Generic.IEnumerable`1'. Only primitive types (such as Int32, String, and Guid) and entity types are supported."
I think you have a pretty nasty code smell going on here, but working with what you have got I wouldn't handle this in a LINQ query like that. Just for the sake of readability I'd do something like
myQuery = myQuery.OrderBy(p =>
(p.HasValidFields()
? p.Seconds.First().Thirds.First().Forths.First().myField
: p.myDefaultField
));
And inside of p's class
private bool HasValidFields
{
get
{
return p.Seconds != null &&
p.Seconds.FirstOrDefault() != null &&
.... ;
}
}
I have the below linq query which takes a text field which may be Y, N or DBnull and populates a boolean? parameter with either True, False or null depending on the value of the field.
var dset = from i in tbdc.Talkbacks
where i.talkback_id == id
select new Talkback(
i.talkback_id, i.acad_period, i.reference,
i.staff_member, i.date_received, i.no_talkers,
i.gender_id, i.names, i.type_id,
i.method_id, i.area_id, i.site_id,
i.category_id, i.date_closed, i.expenddate,
i.acknowledgementtarget,
(i.targetmet == "Y") ? true :
((i.targetmet == "N") ? false : null),
(i.acknowledgementtargetmet != "N") ? true : false
The problematic line is
(i.targetmet == "Y") ? true : ((i.targetmet == "N") ? false : null)
After reading up I found some documentation which states that the 2nd and 3rd arguments of the inline if need to be of the same type or be implicitly convertible to one another.
My question is, how do I get around this limitation to achieve my desired result?
I am relatively new to C# so am not familiar with all its quirks/capabilities yet.
My suggestion would be to replace it with :
(i.targetmet != null) ? (bool?)(i.targetmet == "Y") : null;
the reason why the compiler does not agree without the cast is that even if you store it into a nullable structure, the ternary operation checks if the results are compatible through an implicit conversion.
Results true and false are treated as bool literals, not bool?, thus not implicitly convertible to null. Casting either results to bool? will make them comparable. The one I suggested has an implicit convertion between bool? and null, and this works too:
(i.targetmet != null) ? (i.targetmet == "Y") : (bool?)null;
Which is an implicit conversion between a bool and bool?. I arbitrary prefer the first one..
You can explicitly convert one or more of the expressions to a bool?:
(i.targetmet == "Y") ? true : ((i.targetmet == "N") ? (bool?)false : (bool?)null)
I have the following LINQ expression that's not returning the appropriate response
var query = from quote in db.Quotes
where quote.QuoteStatus == "Estimating" || quote.QuoteStatus == "Rejected"
from emp in db.Employees
where emp.EmployeeID == quote.EmployeeID
orderby quote.QuoteID descending
select new
{
quote.QuoteID,
quote.DateDue,
Company = quote.Company.CompanyName,
Attachments = quote.Attachments.Count,
Employee = emp.FullName,
Estimator = (quote.EstimatorID != null && quote.EstimatorID != String.Empty)
? db.Employees.Single (c => c.EmployeeID == quote.EstimatorID).FullName
: "Unassigned",
Status = quote.QuoteStatus, Priority = quote.Priority
};
The problem lies in the Estimator = (quote.EstimatorID != null && quote.EstimatorID != String.Empty) ? db.Employees.Single(c => c.EmployeeID == quote.EstimatorID).FullName : "Unassigned" part.
I NEVER get it to evalueate to "Unassigned", on the ones that are supposed to, it just returns null. Have I written this wrong?
Try this and see if you're receiving the same values:
Estimator = ((!string.IsNullOrEmpty(quote.EstimatorID) && !string.IsNullOrEmpty(quote.EstimatorID.Trim())
? (db.Employees.Single(c => c.EmployeeID == quote.EstimatorID)).FullName
: "Unassigned")
If that doesn't work, try replacing the check in the ternary expression (!string.IsNullOrEmpty part) with false and see if you reach "Unassigned". I've found that sometimes, when you use a ternary expression in a LINQ query, you have to wrap the whole thing in parentheses.
I think your expression is correct, although I would advise changing it to !string.IsNullOrEmpty(quote.EstimatorID) for clarity.
Note however that your expression could still return null if db.Employees.Single(c => c.EmployeeID == quote.EstimatorID).FullName returns null.
Then it looks like quote.EstimatorID is not null or empty string. Is db.Employees.Single() returning null here? Debug it - put breakpoints into those parts of the expression (putting them on separate lines, if necessary). If you can't do that wrap methods around them that call Debug.WriteLine() or similar.