I want to take max value of ushort list and when that list is empty I want set "1" for default value.
For example:
List<ushort> takeMaxmumId = new List<ushort>();
var max = takeMaxmumId.Select(x=>x).DefaultIfEmpty(1).Max();
In my Example Visual Studio Show me this error:
'IEnumerable' does not contain a definition for
'DefaultIfEmpty' and the best extension method overload
'Queryable.DefaultIfEmpty(IQueryable, int)' requires a
receiver of type 'IQueryable'
When my list type were int I have not any problem, What is this problem in ushort type? And how can I fix this with best way?
The problem is that Select produces an IEnumerable<ushort>, while DefaultIfEmpty supplies an int default. Hence, the types do not match.
You can fix this by forcing ushort type on the default:
var max = takeMaxmumId.Select(x=>x).DefaultIfEmpty<ushort>(1).Max();
// ^^^^^^^^^^^^^
// This part can be removed
Demo.
You can also convert sequence elements to int:
var max = takeMaxmumId.Select(x => (int)x).DefaultIfEmpty(1).Max();
Since your data type is ushort you will have to staisfy the alternative orverload of DefaultIfEmpty extension method. i.e DefaultIfEmpty(this IEnumerable source, TSource defaultValue);
So you will have to cast to your source to type ushort.
var max = takeMaxmumId.Select(x => x).DefaultIfEmpty( (ushort) 1).Max();
You could try this one:
var max = takeMaximumId.DefaultIfEmpty((ushort)1).Select(x => x).Max();
The problem is due to the fact that passing 1 without the cast to ushort you can't apply the extension method DefaultIfEmpty, because 1 is interpreted as int and the list you want to apply this is of type List<ushort>. If you write the following
var max = takeMaximumId.DefaultIfEmpty(1).Select(x => x).Max();
you would get the error message below, which explains the above
statement:
'List' does not contain a definition for 'DefaultIfEmpty' and
the best extension method overload
'Queryable.DefaultIfEmpty(IQueryable, int)' requires a
receiver of type 'IQueryable'
As a side note, despite the fact that dasblinkenlight has already mentioned this in his post, you don't need at all the Select, since you don't make any projection there. You just want to get the maximum value of the numbers contained in your list.
Related
Hey guys im not sure if what i want to do is right or not,
i have diffrent status in our network,which i have created a ENUM class for it:
public enum AllMachinesStatus
{
STOP,
START,
LINKDOWN,
ERROR,
LINK_UP,
IDLE,
}
in database i there is a service which binds these fields,they are all int,the show the number of the machine in each status which should vary from time to time,,now i want to get this data with linq and bind my class,do you think its a right way?or i should create a normal class with a constructor which whenever i call the class i can have the data?
var rslt=(from s in db.Machines
select new AllMachinesStatus{
//here i dont have access to the properties of enum class to bind them with Count()
}
If s in an integer with a valid value for AllMachinesStatus, try:
from s in db.Machines select (AllMachinesStatus)s
Basically, it is casting the int to AllMachinesStatus enum
Your issue is improper usage of enum here.
enum does not have a constructor, it is a strong type that has an implicit value type, but it is mostly suitable for signaling and flagging.
In this method, you would evaluate on s and either cast the correlating int value of s or a field\property of s to AllMachinesStatus or do Enum.Parse using s or a field\property of s (i.e. s.Status).
note that AllMachinesStatus enum has implicit int values.
public enum AllMachinesStatus
{
STOP, // 0
START, // 1
LINKDOWN, // 2
ERROR, // 3
LINK_UP, // 4
IDLE, // 5
}
Example of Enum.Parse with s.Status
// note that 'false' is being passed for case insensitive behavior in the method
var rslt=(from s in db.Machines
select (AllMachinesStatus)Enum.Parse(typeof(AllMachinesStatus), s.Status, false));
Alternatively,
if s had a field (I'll call BitFlag for purpose of example) correlating to the int value, you could us the following:
Example of casting int to AllMachinesStatus
var rslt=(from s in db.Machines
select (AllMachinesStatus)s.BitFlag);
Doc References:
MSDN System.Enum
MSDN Enum.Parse
EDIT1:
Include examples and corrected sentiment of using Enum.GetName to Enum.Parse
EDIT2:
update s to use question comment referenced s.Status existence.
I've tried a lot of things but the most logical one for me seems this one:
int divisor = AllMyControls.Take(p => p.IsActiveUserControlChecked).Count();
AllMyControls is a Collection of UserControls, what I want to know is how many UserControls have the IsActiveUserControlChecked property set to true.
What I get in VS is:
Cannot convert lambda expression to type 'int' because it is not a delegate type
What's wrong with my expression?
int divisor = AllMyControls.Where(p => p.IsActiveUserControlChecked).Count()
or simply
int divisor = AllMyControls.Count(p => p.IsActiveUserControlChecked);
Since you are a beginner, it would be worthwhile to take a look at Enumerable documentation
Why not directly use Count? That == true statement is also highly redundant.
int divisor = AllMyControls.Count(p => p.IsActiveUserControlChecked);
Also, you are getting an error on your Take method because it is waiting for an int. You need to specify the number of contiguous elements from the start of the collection you want to get, you cannot put a lambda expression. You need to use TakeWhile for that. So
int divisor = AllMyControls.TakeWhile(p => p.IsActiveUserControlChecked == true).Count();
would have been correct, but would not work the way you expect it; it stops once the condition is broken. So if AllMyControls contains true, true, false, true, TakeWhile with Count will return 2 instead of your expected 3.
The parameter for Take requres an int and you are passing in a delegate/ lambda expression. Take is designed to just take the first count of the elements.
You can use the Count method and pass in a delegate to count the elements that fit its criteria. This way you only iterate the IEnumerable once, rather than first culling out the ones that don't fit your criteria, and then again to actually count them.
AllMyControls.Count(p => p.IsActiveUserControlChecked);
Do not KISS
int divisor = AllMyControls.Count(p => p.IsActiveUserControlChecked);
Try
int divisor = AllMyControls.Where(x => x.IsActiveUserControlChecked == true).Count();
Can't figure out how to build an expression that compares an enum type with an int. I have a MVC site with Kendo components embedded. In the view-class, the property is an ENUM, but the view returns an Int32 (the source is a Kendo IFilterDescriptor).
So the problem is...: I receive an int from the view, build the expression, that fails because an enum is expected. Fix this by converting the int to its enum representation, but then it fails when querying the database, because the database expect an Int32.
public static Expression<Func<DOMAIN, bool>> GetExpressionsFromFilterDescription<DOMAIN, VIEW>(this IEnumerable<IFilterDescriptor> _this)
{
Expression expressions = null;
ParameterExpression pe = Expression.Parameter(typeof(DOMAIN), "x");
foreach (FilterDescriptor item in _this)
{
MemberExpression member = Expression.Property(pe, item.Member);
ConstantExpression value = Expression.Constant(item.Value);
Expression exp = null;
switch (item.Operator)
{
case FilterOperator.IsEqualTo:
exp = Expression.Equal(member, value);
From what I understand, Expression.Call() should be able to fix this, I just can't figure out how to do this.
Any help would be appreciated.
BR Peter
UPDATE
Converting the value like below, does fix the expression problem (the "The binary operator Equal is not defined for the types..." error), but then I get a new error querying the database: "Type mismatch in NHibernate.Criterion.SimpleExpression: Status expected type System.Int32, actual type...".
exp = Expression.Equal(member, Expression.Convert(value, typeof(MyEnum)));
The fix, as I see it, is either by building my own compare (Expression.Call ?) or by telling that the type (in item.Member) is an int and not an enum, but I don't know how or if this is the right way.
Thanks.
UPDATE UPDATE
It seems like that the second part of the problem is due to NHibernate.QueryOver and its limitations. Once changed to NHibernate.Linq, the query part of the problem, went away.
As for the Expression part I have fixed the problem by adding an attribute to the property telling how the value should be converted. I am not using Expression.Convert (but I could have), the conversion happens in the received filter description before building the expression.
Thanks for your time and help. I will accept the answers related to Expression.Convert since it could fix the problem. I still do want to understand the Expression.Call() method - so please feel free to comment on that. Thanks.
Wouldn't this do the trick?
MemberExpression member = Expression.Convert(
Expression.Property(pe, item.Member), typeof(int);
ConstantExpression value = Expression.Constant((int)item.Value);
You can use Expression.Convert to convert an expression of an enumtype to anint` (assuming that the underlying type of the enum is an int).
I don't exactly see your enum you are comparing to, is it item.Value?
You can always cast the value of an enum to a number to compare it to a number or feed it into systems that don't recognize enums:
enum Blah
{
Tom,
Rick,
Harry
}
if ((Int32)Blah.Tom == 0)
{
}
Hi I have the following Linq in my project:
string claim;
claim = txtImageVerificationClaimSearch.Text;
var claimsearch = (from x in dbContext.view_ImageVerification_Shortened
where(x.intClaimID = claim)
select new
I'm getting some error messages:
Cannot implicitly convert type 'string' to 'int'
I know what the error means, but I don't know the syntax to fix it.
I also am getting the error message:
Error 2: Cannot convert lambda expression to type 'string' because it is not a delegate type
C:\_Applications-TFS\IVS\Main\ImageVerificationSystem\ImageVerificationSystem\Default.aspx.cs 97 36 ImageVerificationSystem
I am also getting this:
Delegate 'System.Func<ImageVerificationSystem.view_ImageVerification_Shortened,int,bool>' does not take 1 arguments
can anyone tell me what I'm doing wrong?
Your problem is that claim is a string and intClaimID is an int. In other words you're comparing apples and oranges.
You either need to do something like:
where x.ClaimName == claim
Or you need to ask the user to enter a number in which case you'll have to convert it to ant int (from the string of the textbox)
int userClaimID = int.Parse(claim); // or TryParse
and then add it to your expression
where x.intClaimID == userClaimID
You need double = to do comparison. Also you are trying to compare string to int. I would suggest converting claim to int first.
int claimId = int.Parse(claim);
var claimsearch = (from x in dbContext.view_ImageVerification_Shortened
where(x.intClaimID == claimId)
select x);
int claimInt = Int.Parse(claim);
...
You don't need that brackets use
from x in dbContext.view_ImageVerification_Shortened
where x.intClaimID.ToString() == claim
select new { .. }
Also == is used for comparison = is used for assignments.
If you want to compare two incompatible types you need to convert one of them.In this case either use ToString on integer (intClaimID), or parse claim to integer.
I read values from an local Access mdb-file. One value is stored as string in the db and I have it in a table. When using the GetType() method it return "System.String" and I can print it on the console without a problem but when I want to use it as an attribute for another method (requires a string) I get an error ("Cannot convert from 'object' to 'string'" and the same for 'int'). The same problems occur with some int values.
Am I doing something wrong or what is the problem in that case?
Console.WriteLine(dt.Rows[0][ProjName]); //prints project_name
Console.WriteLine(dt.Rows[0][ProjName].GetType()); //print "System.String"
Project = new Project(dt.Rows[0][ProjName], dt.Rows[0][MinDay], dt.Rows[0][MinWeek], dt.Rows[0][DayWeek]); //Error
Project = new Project(Convert.ToString(dt.Rows[0][ProjName]), Convert.ToInt32(dt.Rows[0][MinDay]), Convert.ToInt32(dt.Rows[0][MinWeek]), Convert.ToInt32(dt.Rows[0][DayWeek])); //Works Fine
Constructor for the Project Class:
public Project(string projectName, int hoursPerDay, int hoursPerWeek, int daysPerWeek)
You have stated in your answer is works when converting, and it is necessary as they are not strings and integers. They are objects. You can create a methid to handle it if you want.
public Project CreateProject(object projectName, object hoursPerDay, object hoursPerWeek, object daysPerWeek)
{
return new Project(projectName.ToString(), Convert.ToInt32(hoursPerDay), Convert.ToInt32(hoursPerWeek), Convert.ToInt32(daysPerWeek);
}
You have to explicitly cast the objects:
To cast to string use:
Object.ToString();
To cast to integers use:
Int32.TryParse(String, out int);
Your constuctor becomes
Project = new Project(dt.Rows[0][ProjName].ToString(), Int32.Parse(dt.Rows[0][MinDay]), Int32.Parse(dt.Rows[0][MinWeek]), Int32.Parse(dt.Rows[0][DayWeek]));
Note: Using Int32.Parse instead of Int32.TryParse assumes that the argument provided is a valid int at all times and does not give you a way to check if the casting has succeeded.
dt.Rows[0][ProjName] returns type object, and your method expects string. Even though you know it to be a string, it is not obvious to the compiler and must be specified explicitly using a cast, as you show in your last example, although just casting should be more efficient than converting unnecessarily:
Project = new Project((string)dt.Rows[0][ProjName], ...