Convert string to int for sum in linq - c#

I have a column requestAmount that is nvarchar(100).
I need to calculate sum :
int? sum = q.Sum(g => g.requestAmount);
I got this error:
Error 26 Cannot convert lambda expression to delegate type
'System.Func<samtaApplication.DbLayer.tblMaterial,int>' because some
of the return types in the block are not implicitly convertible to the
delegate return type
How can I convert string to int?

In linq to entities you can always materialize query first, so you will operate on linq to objects
int? sum = q.AsEnumerable().Sum(g => Int.Parse(g.requestAmount));
Note that it will load whole q from db
EDIT:
if requestAmount is nullable then use:
int? sum = q.AsEnumerable().Sum(g => Convert.ToInt32(g.requestAmount));
Convert.ToInt32 will return 0 when null is passed as parameter

int? sum = q.Sum(g => Int32.Parse(g.requestAmount));

A string can be null or empty, so, keep it safe using a filter with Where and after it applying and Sum , for sample:
int dummy;
int result = q.Where(g => int.TryParse(g.TryParse(g.requestAmount, out dummy))
.Sum(g => int.Parse(g.requestAmount.Trim()));

have you tried using the int.TryParse?

Related

Why are these two LINQ queries different? When they seem to be the same

I would like know why these two LINQ queries are different, or why one works and the other does not? Obviously the compiler says they are different, but I can't seem to find out why?
I want the first query to work, but no matter what I do It won't work.
The below LINQ query gives me an error of,
Cannot implicitly convert type 'int?' to
'System.Collections.Generic.IEnumerable'
public static IEnumerable<int?> GetTenantFacilityCosts(int? code, DateTime date, int number)
{
return DataContext.Facility_Cost_TBLs.
Where(p => p.Tenant_Code == code &&
p.Code_Date == number &&
p.Date_Year == date.Year &&
p.Date_Month == date.Month).
FirstOrDefault().Tenant_Portion;
}
But this query below gets the int value that I am trying to get and does not throw an error.
int? facilityCost =
DataContext.Facility_Cost_TBLs.
Where(p => p.Tenant_Code == selectedTenant.Tenant_Code &&
p.Code_Date == 10 &&
p.Date_Year == date.Year &&
p.Date_Month == date.Month).
FirstOrDefault().Tenant_Portion;
Why are these two queries differnt and how would I get the first one to work correctly?
As you can see from the one that works, the result of your query is an int?. When you've turned that to a function the return type of your function is IEnumerable<int?>.
You function should be
public static int? GetTenantFacilityCosts(int? code, DateTime date, int number)
{
...
}
The Linq query returns a nullable int i.e. int?, the reason it works for the second is because it is assigning the value to a int?.
The second one is returning a int? on a method that is trying to return: IEnumerable<int?>. If you want to return an enumerable of the results you need to remove the FirstOrDefault from the query. And judging by the method name, i.e. the plural Costs, this is what you want.
However if you only want one result change the method signature to:
public static int? GetTenantFacilityCosts(int? code, DateTime date, int number)

passing in nullable Expression<Func<T, TResult>>? as method parameter?

So i have a method
public IPagedList<MyObject> GetAll<T>(Expression<Func<MyObject, T>>? orderBy,
int pageNumber = 1, int pageSize = 10)
{
return dataContext.MyObjects
.OrderBy(orderBy.HasValue ? orderBy.Value : <WHAT GOES HERE?>)
.ToPagedList<MyObject>(pageNumber, pageSize);
}
My goal is to have the orderBy parameter optional, if orderBy is null then default the order to the property MyObject.Id.
I've tried .OrderBy(orderBy.Hasvalue ? orderBy.Value : x => x.Id) but getting this error:
Type of conditional expression cannot be determined because there is no implicit conversion between 'System.Func<MyObject, T>' and 'lambda expression'
What am I doing wrong?
Thanks!
There are a few problems with your code
Expression<TDelegate> is a class, so it's nullable already; you can simply test if orderBy == null. Nullable<T> has a generic constraint that T must be a struct, so Expression<Func<MyObject, T>>? won't compile.
Next you'll have the problem that because the type T isn't bound inside the method, but x.Id is. In other words, you won't be able to create use the conditional operator to choose between a value of Expression<Func<MyObject, T>> and Expression<Func<MyObject, int>> (assuming that Id is an int) while still maintaining type information to pass to the OrderBy method.
The solution is to use something along these lines:
public IPagedList<MyObject> GetAll<T>(Expression<Func<MyObject, T>> orderBy,
int pageNumber = 1, int pageSize = 10)
{
IQueryable<MyObject> objects = dataContext.MyObjects;
objects = (orderBy != null) ? objects.OrderBy(orderBy)
: objects.OrderBy(x => x.Id);
return objects.ToPagedList<MyObject>(pageNumber, pageSize);
}
The conditional operator works in this code because regardless of what you pass to OrderBy the return type will be the same, IQueryable<MyObject>.
Note also that you can't simply pass in a null value for orderBy, because T can't be inferred. You'd have to call it like this:
var results = MyClass.GetAll<int>(null);
Ultimately, you'd probably be better off creating two overloads, one that accepts an orderBy expression, and one that doesn't.

how to filter with linq and `contains`

I try to filter my items according to unknown number of filters.
//item.statusId is nullable int
//statusIds is a string
{...
var statusIds = Convert.ToString(items["StatusId"]);//.Split(';');
results = mMaMDBEntities.MamConfigurations.Where(item =>
FilterByStatusId(statusIds, item.StatusId)).ToList();
}
return results;
}
private bool FilterByStatusId(string statusIds, int? statusId)
{
return statusIds.Contains(statusId.ToString());
}
But I get this error:
LINQ to Entities does not recognize the method 'Boolean FilterByStatusId(System.String, System.Nullable1[System.Int32])' method, and this method cannot be translated into a store expression.`
Any idea how to re-write it?
If statusIds is an array then you can do:
results = mMaMDBEntities.MamConfigurations
.Where(item => statusIds.Contain(item.StatusID)).ToList();
Some what similar to SQL Select * from table where ID in (1,2,3)
EDIT:
From your code it appears you have a string with semicolon separated values. You can try the following to get an array of int and later use that in your LINQ expression.
var str = Convert.ToString(items["StatusId"]);//.Split(';');
// string str = "1;2;3;4;5"; //similar to this.
int temp;
int[] statusIds = str.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries)
.Select(r => int.TryParse(r, out temp) ? temp : 0)
.ToArray();
then later you can use the int array in your expression like:
results = mMaMDBEntities.MamConfigurations
.Where(item => statusIds.Contain(item.StatusID)).ToList();
Why not insert the predicate statement directly into the where clause?
like this:
results = mMaMDBEntities.MamConfigurations.Where(item => statusIds.Contains(item.StatusId).ToList();
you might need to convert the string array resulting from the Split to a List or IEnumerable to make this work.
The exception is pretty self-explanatory, the method cannot be converted to a SQL statement in the form you wrote it, but if you write it like above, you should obtain the same result and it will work.

Casting a value to Decimal

Here is my code:
var finiGames = myRepos.Games
.Where(x => x.StatusGameId == (int)StatusGameEnum.Finish
&& x.EndDateTime > DateTime.Today)
.DefaultIfEmpty();
//error line
decimal? sum = finiGames.Sum(x => x.WinCost);
The error I am getting:
Error converting cast a value type "Decimal", because materializuemoe
value is null. The overall result of the type parameter or a request
to use a type that allows the value null.
What is the proper way to get a decimal??
You need to cast the WinCost to a nullable decimal inside the Sum
decimal? sum = finiGames.Sum(x => (decimal?)x.WinCost);
Try adding a ToList() to finiGames. It might kill your performance, but EF probably can't handle the conversion in the data (SQL) layer.
decimal sum = ((decimal?)finiGames.Sum(x => x.WinCost)) ?? 0;

Cannot convert from 'System.Collections.Generic.IEnumerable<int>' to 'System.Collections.Generic.IEnumerable<int?>'

class first
{
private int? firstID;
}
class second
{
private int secondID;
private int secondField;
}
public override Expression<Func<first, bool>> FirstFilter()
{
Contex db = new Contex();
List<second> list = (from p in db.second select p).ToList();
return b => list.Select(p => p.secondID).Contains(b.firstID);
}
and I have error:
cannot convert from 'System.Collections.Generic.IEnumerable' to 'System.Collections.Generic.IEnumerable'
I have tried many different ways, but I just don't know how can I fix it.
Use this:
list.Select(p => p.secondID).Cast<int?>().Contains(b.firstID);
You are getting the problem, because list.Select(p => p.secondID) will be an IEnumerable<int?, but because firstID is int (non-nullable), overload resolution cannot determine a valid overload of Contains to call. You cannot implicitly convert from IEnumerable<int?> to IEnumerable<int>. The Cast extension method works by casting each element to int.
As mentioned in another answer, you could also simply pass in a non-nullable int into Contains:
list.Select(p => p.secondID).Contains(b.firstID ?? 0);
But, do be aware that this might not be want. If the first list contains 0, and firstID is null, the result will be true, because you pass in 0 when the value is null.The Cast version of the expression returns false when firstID is null.
Try providing a default value for firstID if it is null:
return b => list.Select(p => p.secondID).Contains(b.firstID ?? 0);

Categories

Resources