Some difficulties writing a LINQ query - c#

I have the following code:
IsServiceable = _context.Review.Any(r => r.SiteId == x.Id) ? _context.Review.All(r => r.SiteId == x.Id && r.IsValid == true) : true
But as you can see it is not effective because I try to access the database twice in the same row.
I need to write single query(LINQ TO ENTITY) to check if the table named Reviews
has at least one row
where siteId=5 if it doesn't it has to return true,
If table Reviews has at least one row I need to check a boolean column named isValid if, there is at least one row where siteId=5 and isValid column is false I need to return false.

I believe your solution lies in the fact that only in one case do you need to return false - everything else returns true. Therefore, if you find one row where sideId=5 and isValid = false, then return false. Otherwise, return true. Based on your code, I suggest something like the following:
IsServiceable = _context.InspectionReview.Any(r => r.SiteId == x.Id && r.isValid == false) ? false : true;

You most likely have navigation properties so you could try
IsServiceable = _context.Site.Any(s => s.Id == x.Id && s.Reviews.Any(r => r.IsValid));

Related

Linq check value in SQL table always is false

I tried to check if the cost or benefit value exists for the selected Id, then I will get the cost or benefit value from the table.
In the code below my if statement doesn't work and seems to always be false but the return benefit value works fine. Where is the problem?
public string GetCostBenefitAmount(int id)
{
if (db.CostBenefits.Any(c => c.ID == id && !c.Cost.Equals(0)))
{
return db.CostBenefits.Select(c => c.Cost).First().ToString();
}
return db.CostBenefits.Where(c=> c.ID == id).Select(c => c.Benefit).First().ToString();
}
This is my code in windows form for fill txtAmount textBox by GetCostBenefitAmount(int id) method:
var stockIdList = db.CostBenefitRepository.GetAllID();
int id = stockIdList[listBox.SelectedIndex];
CostBenefit costBenefit = db.GenericCostBenefitRepository.GetById(id);
txtStockName.Text = listBox.SelectedItem.ToString();
txtSoldAmount.Text = costBenefit.SoldAmount.ToString();
ComboCostBenefit.SelectedItem = db.CostBenefitRepository.GetCostBenefitOperation(id);
txtAmount.Text = db.CostBenefitRepository.GetCostBenefitAmount(id);
The Object.Equals method determines whether two object instances are equal. Try if (db.CostBenefits.Any(c => c.ID == id && c.Cost != 0)). For more info on the Object.Equals function see this post.
Edit:
As #Gert Arnold commented, the issue was in the return db.CostBenefits.Select(c => c.Cost).First().ToString(); where there was no filtering done before returning.
I think equals is only when you are using in a join. So just use
c.Cost != 0
instead.

Lambda treating null as false in bool where clause

I have the following Entity Framework lambda query:
public IList<MyClass> GetMyClass(int id, bool show)
{
using (var ctx = new DbContext())
{
return ctx.MyClasses.Where(x =>
x.Id == id &&
x.Show == show // <-- nullable bool
.OrderByDescending(x => x.CreationDate).Take(100).ToList();
}
}
My front end view has passed the show boolean down indicating the users preference for what to return.
In the database, the show property is nullable.
This is a very heavy query, so I have limited it to 100 at a time, thousands of rows are null, thousands are true and thousands are false.
Question
How can I say, without making the query inefficient, psuedo code:
.Where(x => x.Show == show) (where null or false == false)
As it stands, if I pass False down, the nulls are excluded, and I need them to be classed as False.
I cannot change the database
how about
(x.Show ?? false) == show
The following code should return records with Show == True when show == true, and records with Show == False or NULL when show == false
private void Repeat(object state)
{
public IList<MyClass> GetMyClass(int id, bool show)
{
using (var ctx = new DbContext())
{
return ctx.MyClasses.Where(x =>
x.Id == id &&
(x.Show == show || !show && x.Show == null)
.OrderByDescending(x => x.CreationDate).Take(100).ToList();
}
}
}
Just another way to think about the expression. Not a good practice in LINQ to Entity.
(x.Show == true) == show

Use of Contains with one Except in LINQ

I am trying to get a list of Menus which does not contain "license".
var menus= MenuRepo.GetAll().Where(x => x.Name.Contains("license") == false)
But now i want to exclude one of them, ie., "licenseUser"
I need "licenseUser" in the list.
How can i achieve this?
var menus = MenuRepo.GetAll().Where
(
x => !x.Name.Contains("license") || x.Name == "licenseUser"
);
(note that a == false when a is boolean is the same as !a, and it's shorter to write)
Just add an OR condition which checks whether the menu name is equal to "licenseUser":
var menus = MenuRepo.GetAll().Where(menu => !menu.Name.Contains("license") || menu.Name == "licenseUser");

how to retrive crm attribute value with linq when bool is set to false or true

var emailAddress = xrmContext.ftr_EmailAddressSet
.Where(e => e.ftr_EmailAddressId == emailAddressId
&& e.ftr_IsDeleted == false))
.Select(e => e.ftr_EmailAddress1).FirstOrDefault();
The above image is a crm entity and I need to retrieve emailaddress when "Is Deleted" option is "false(No)". I need and tried using a linq query in my C# .cs file.
When I use my code it returns a null value. When I remove this line:
e.ftr_IsDeleted == false
it returns emails with true and false correctly but I need it to work for only false.
Try using two where conditions like this:
var emailAddress = xrmContext.ftr_EmailAddressSet.Where(e => e.ftr_EmailAddressId == emailAddressId).Where(e.ftr_IsDeleted == false).Select(e => e.ftr_EmailAddress1).FirstOrDefault();
Hope this helps.

How a Boolean method should not return for case sensitive c#

I have a Boolean function which checks the names from database, If any name exists in database which returns true. my function is
public bool rawMtrlExists(string strRawMtrl)
{
var rwMtrl = prodctsDC.productsnrwmtrls.Where(c => c.item_Ctgry == 'R' || c.item_Ctgry == 'B'||c.item_Ctgry=='G').Distinct().ToArray();
return rwMtrl.Count(d => d.item_Name == strRwMtrl) > 0;
}
My problem is.. If my strRawMtrl orgument having the same word but with casesensitive, the method returning false. I mean name in database field is Central Processing Unit. Iam passing as central processing unit. In this case It is returning false but I need true. Please anybody help me to return not for case sensitive words too.
You can use overloaded Equals method with StringComparison.OrdinalIgnoreCase:
d.item_Name.Equals(strRwMtrl, StringComparison.OrdinalIgnoreCase)
Another hacky way which I don't prefer since it creates two more strings in heap:
d.item_Name.ToLower() == strRwMtrl.ToLower()
I think you can use this. Using ToArray() forces next parts of query to run locally. Also Disticnt() redundant.
public bool rwMtrlExists(string strRwMtrl)
{
return prdTcnDC
.productsnrwmtrls
.Where(c => c.item_Ctgry == 'R'
|| c.item_Ctgry == 'B'
|| c.item_Ctgry == 'G')
.Any(d => d.item_Name.ToLower() == strRwMtrl.ToLower());
}

Categories