Linq check value in SQL table always is false - c#

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.

Related

passing linq anonymous result to iqueryable object for another query

I have two tables (tbPerson and tbDataLog) where I need to return Id from one table (tbPerson) after checking certain conditions on both. After this, this result should be passed to another query. My first query returns the Id (primary key of a table) successfully and I need to pass these ids to another query so that it return me data based upon these Id. I also has an IQueryable type base object to check certain conditions to fetch data.
IQueryable<tbPerson> dataset
and I cannot changes this from Iqueryable to other as it will break other part of the code)
My first linq statement:
public static IQueryable<LogResults> GetResultsForYes()
{
Databasename ents = new Databasename();
var ids = (from f in ents.tbPerson
join g in ents.tbDataLog
on f.InfoID equals g.RefId
where g.Tag == "subscribed" && g.OldValue == "No" && g.Action == "Modified"
select new LogResults { _LogID = f.Id }).OrderBy(x => x._LogID);
return ids;
}
public class LogResults
{
public int _LogID { get; set; }
}
I access my result something like this where I can see in debugger all the Ids.
IQueryable<LogResults> log = GetResultsForYes();
Problem comes, when I tried to get records from tbPerson based upon these returned Id.
dataset=log.where(x=>x._LogID != 0);
I get this error:
Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Linq.IQueryable'. An explicit conversion exists(are you missing a cast)?
Any suggestions or some other good approach is welcome.
I love this thing about stackoverflow. when we write questions we force our brain to think more deeply and after 30 mins of posting this question, I solved it in a simple way. Sometimes we overcomplicated things!
var ids = (from f in ents.tbPerson
join g in ents.tbDataLog
on f.InfoID equals g.RefId
where g.Tag == "subscribed" && g.OldValue == "No" && g.Action == "Modified"
select new { f.Id }).ToArray();
var allId = ids.Select(x => x.Id).ToArray();
dataset = dataset.Where(x => allId.Contains(x.Id));
#ankit_sharma : I have not tested yours but will give a try and come back to you. Thanks for giving time and effort.
IQueryable<tbPerson> dataset=log.where(x=>x._LogID != 0);
The result of log.where(x=>x._LogID != 0) is an IQueryable<LogResults>, and you are trying to assign this result to dataset of type IQueryable<tbPerson>, two diferent types.
EDIT:
I see you make a join to get the tbPerson ids, and then you do a second query to get the persons. You could get the persons in the first join.
I just modify your code:
IQueryable<tbPerson> persons = from person in ents.tbPerson
join g in ents.tbDataLog
on person.InfoID equals g.RefId
where g.Tag == "subscribed" && g.OldValue == "No" && g.Action == "Modified"
select person;

Method has no supported translation to SQL

My project is using MVC 4 C# LINQ to SQL.
For some reason the method used to get data for one of my properties is giving a "has no supported translation to SQL" error. The method to fetch this data is nearly identical to the method of another property in the same query except the one that works grabs a string where the one that doesn't gets a decimal.
Exact error code:
Method 'System.Decimal GetModelDifficulty(System.String)' has no supported translation to SQL.
I've tried numerous variations on the below code but I always get the same error as above:
public List<ProductionSchedule> GetBaseProductionSchedule(DateTime selectedDate)
{
var spaList = (from x in db.WO010032s
join y in db.MOP1042s on x.MANUFACTUREORDER_I equals y.MANUFACTUREORDER_I into x_y
where x.STRTDATE == selectedDate && (x.MANUFACTUREORDERST_I == 2 || x.MANUFACTUREORDERST_I == 3)
from y in x_y.DefaultIfEmpty()
select new ProductionSchedule()
{
MO = x.MANUFACTUREORDER_I,
BOMNAME = x.BOMNAME_I,
SpaModel = x.ITEMNMBR,
MoldType = GetMoldType(x.ITEMNMBR.Trim()),
SerialNumber = y.SERLNMBR,
Difficulty = GetModelDifficulty(x.ITEMNMBR.Trim())
}).OrderByDescending(x => x.Difficulty).ToList();
return spaList;
}
public string GetMoldType(string model)
{
return db.SkuModelDatas.Where(x => x.Value == model).Select(x => x.MoldType).FirstOrDefault();
}
public decimal GetModelDifficulty(string model)
{
return (decimal)db.SkuModelDatas.Where(x => x.Value == model).Select(x => x.Difficulty).FirstOrDefault();
}
Well I've tweaked the code around enough times to where I've stumbled on a variation that works:
public List<ProductionSchedule> GetBaseProductionSchedule(DateTime selectedDate)
{
var spaList = (from x in db.WO010032s
join y in db.MOP1042s on x.MANUFACTUREORDER_I equals y.MANUFACTUREORDER_I into x_y
where x.STRTDATE == selectedDate && (x.MANUFACTUREORDERST_I == 2 || x.MANUFACTUREORDERST_I == 3)
from y in x_y.DefaultIfEmpty()
select new ProductionSchedule()
{
MO = x.MANUFACTUREORDER_I,
BOMNAME = x.BOMNAME_I,
SpaModel = x.ITEMNMBR,
MoldType = GetMoldType(x.ITEMNMBR.Trim()),
SerialNumber = y.SERLNMBR,
Difficulty = GetModelDifficulty(x.ITEMNMBR)
}).ToList();
return spaList.OrderByDescending(x => x.Difficulty).ToList();
}
public string GetMoldType(string model)
{
return db.SkuModelDatas.Where(x => x.Value == model).Select(x => x.MoldType).FirstOrDefault();
}
public decimal GetModelDifficulty(string model)
{
decimal difficulty = (String.IsNullOrEmpty(model)) ? 0M : Convert.ToDecimal(db.SkuModelDatas.Where(x => x.Value == model.Trim()).Select(x => x.Difficulty).FirstOrDefault());
return difficulty;
}
Why it worked when trapping for null string for x.ITEMNMBR (model parameter) in one method and not the other and needing to OrderByDescending outside of the main LINQ query, I have no idea.
Thanks for all the suggestions and help with this.
The problem is your query is calling code that LINQ cannot translate into SQL.
First try this, it may help. There may be a problem with your (decimal) cast. Modify your method GetModelDifficulty to the following:
public decimal GetModelDifficulty(string model)
{
return Convert.ToDecimal(db.SkuModelDatas.Where(x => x.Value == model).Select(x => x.Difficulty).FirstOrDefault());
}
If that doesn't work I'm afraid you'll have to break your query down further to narrow down the issue. Use the documentation provided here: Standard Query Operator Translation (LINQ to SQL) to be sure that any extension methods you are using have supported translations.
If you run into a piece of code that cannot be translated, you may need to declare a separate variable with the necessary value already stored inside of it, that you can then use inside of your query.
I think it's because your call to FirstOrDefault() can return a null value. When you assign to a typed object you can use ? operator to signify that it can be null:
decimal? myDec = <some code returning decimal value or null>
Then you can check if myDec is null or not by:
myDec.HasValue

How to query child tables values

I have 2 tables: POHeader and PODetail. I want to return all POHeaders that have an associated PODetail.ItemId = intItemId. How can I do this in LINQ?
This is what I've tried.
First I have a method in my Repository that uses the Include parameter to include the PODetails:
public IQueryable<POHeader> SearchForWithDetails(int intFacilityId)
{
return DbSet.Include("PODetails").Where(x => x.FacilityId == intFacilityId);
}
Then the result of that gets passed to:
public IQueryable<POHeader> SearchForPODetailsByItemId(IQueryable<POHeader> poHeaders, int intItemId)
{
//This returns a type of PODetail not POHeader
var q = poHeaders.SelectMany(c => c.PODetails).Where(c => c.ItemId == intItemId);
//In this case, I can't figure out the syntax :(
var p = from poHeader in poHeaders
let filteredPOs = from poDetail in poHeader.PODetails
where poDetail.ItemId == intItemId
select ????
return p;
}
What is the correct way to do this?
Also, I can foresee needing 2 results of this:
just return a IQueryable
return a joined table result.
Try this;
var result = poHeaders.Where(e => e.PODetails.Any(a => a.ItemId == intItemId));
Assuming your a Header->Detail is a 1-to-many relationship, and Detail has a navigation back to it's header called .Header:
public IQueryable<POHeader> SearchForPODetailsByItemId(IQueryable<POHeader> poHeaders, int intItemId)
{
var headersForThisItem = poHeaders.SelectMany(pod => pod.PODetails).Where(pod => pod.ItemId == intItemId)
.Select(pod=> pod.Header).Distinct();//.Distinct to eliminate duplicates when 2 Details have the same header. Not necessary if ItemId filter naturally provides distinct results.
return headersForThisItem ;
}
Untested, but I think that will give you what you want.

Return first item in list if FirstOrDefault returns null

I've got a List of products, I need to get the item from the list with a specific product Id that I get from a querystring parameter. However, I may not always have a product Id passed to me. If I don't have a product Id, I need to default to the first product in the list.
At the moment I have:
#Model.Products.FirstOrDefault(x => x.Id == productId);
This just selects the product with that specific Id, if there isn't one, it will default to null.
Is there a way to achieve what I want?
It sounds like you want:
var product = productId == null ? Model.Products.FirstOrDefault()
: Model.Products.FirstOrDefault(x => x.Id == productId);
...
#product
or you could mean:
#(Model.Products.FirstOrDefault(x => x.Id == productId) ??
Model.Products.FirstOrDefault())
What happens if you try something like this?
#if (productId != null) // assuming it's nullable
{
#Model.Products.FirstOrDefault(x => x.Id == productId)
}
else
{
#Model.Products.FirstOrDefault()
}
I know this may look a little cumbersome, but it's quite clear what it's doing (think if somebody else has to maintain it) and it should work.
But in reality I'd probably rather set this up in a ViewModel and then just access the value which I knew would be correct.
Hey Check this it may help you
MSDN link : http://msdn.microsoft.com/en-us/library/bb340482.aspx
List<int> months = new List<int> { };
// Setting the default value to 1 after the query.
int firstMonth1 = months.FirstOrDefault();
if (firstMonth1 == 0)
{
firstMonth1 = 1;
}
Console.WriteLine("The value of the firstMonth1 variable is {0}", firstMonth1);
// Setting the default value to 1 by using DefaultIfEmpty() in the query.
int firstMonth2 = months.DefaultIfEmpty(1).First();
Console.WriteLine("The value of the firstMonth2 variable is {0}", firstMonth2);
/*
This code produces the following output:
The value of the firstMonth1 variable is 1
The value of the firstMonth2 variable is 1
*/

Bool issue - changing value

Morning all.
I have the following method that I use to to try and bring back a bool:
public static bool GetShowCatSubProdStatus(string memberid, string username)
{
MyEnts showcatsubprodstatus = new MyEnts.PDC_VDSOREntities35();
var r = from p in showcatsubprodstatus.tblKeyAccountInfoes
where p.MemberID == memberid && p.UserName == username
select p.ShowCatSubProd;
return r.Any();
}
When I call this method and debug it, the result is correct. However, when I run this method in a page load, although the method result returns the correct result, when I step through, the boolean value changes!
bool showcatsubprodstatus = MyEnts.GetShowCatSubProdStatus(_memberid, _username);
if (showcatsubprodstatus != true)
{
panCatSubProd.Visible = false;
}
Can someone explain what is going on here and how I can solve this puzzler?!
PS: Apologies for being thick.
EDIT - Right, narrowed it down to the variable. It is always return 'true' regardless of the method result?!?!
This piece of code returns an IEnumerable<bool> :
var r = from p in showcatsubprodstatus.tblKeyAccountInfoes
where p.MemberID == memberid && p.UserName == username
select p.ShowCatSubProd;
By calling the .Any() you are asking it if there are any items in the IEnumerable. If there are you return true;
That is why you always get true back, because it always finds something.
The solution
Either you go for calling .SingleOrDefault() which returns the only element there is (if there is one) or returns the default value of that type.
var r = from p in showcatsubprodstatus.tblKeyAccountInfoes
where p.MemberID == memberid && p.UserName == username
select p.ShowCatSubProd;
return r.SingleOrDefault(); //assuming p.ShowCatSubProd is a bool and not a Nullable<bool> else you need to adjust your return type or cast it to a boolean using .GetValueOrDefault().

Categories