Hi all and thanks in advance, I'm stumped on how to use a where clause with the conditional statement that I need to execute. I have two grids of information, one grid is dependent on the other for determining what shows. In the first grid the Date field can be a date or it can say Never.
The first grid's data is like so:
ID Date Title
--- ----- ------
12 Never Home
13 Never School
14 Never Work
The second grid will only show one row of the three depending on what the value of the Date field is, in this example it should be:
ID Date Title
--- ----- ------
12 Never Home
This information is pulled into a List that I want to iterate through using LINQ. What I want to achieve is:
If(All Date values == 'Never')
Then pull the first one (12)
else
if(Date has value)
then pull the first that has a date
myList.Where(??what goes here??).Select(t => t).FirstOrDefault();
var record = myList.FirstOrDefault(m => !m.Date.Equals("Never"))
?? myList.FirstOrDefault();
i.e. first one that doesn't equal never or null, and if null, just the first one (or null).
You're probably looking for something like this:
var record = myList.All(m => m.Date.Equals("Never"))
? myList.FirstOrDefault()
: myList.FirstOrDefault(m => !m.Date.Equals("Never"));
For more on .All() just look at this MSDN post.
Since you have two rules, you will need an if condition somewhere.
The simplest form that I can think of is something like this:
return myList.All(x => x.Date == "Never") ? myList.FirstOrDefault() : myList.FirstOrDefault(x => x.Date != "Never");
Related
I am trying to get one row per id from a DataTable, and I do not care which row I take. The same id can exist on several rows in the table.
Here's the expression that's giving me trouble:
dt.AsEnumerable().GroupBy(i => i.Field<int>("id")).Select(i => i.First())
Running just this section dt.AsEnumerable().GroupBy(i => i.Field<int>("id") correctly gives me a result of 22 groupings for my DataTable. (I have 22 ids with data in this table)
However, when adding on the .Select(i => i.First()), I am only seeing 10 data rows.
To me this doesn't seem to make any sense. If the GroupBy function managed to find 22 distinct id values, I would expect this logic to grab one of each.
My only other thought is that maybe it's just a weird side effect of viewing this data through a watch in Visual Studio rather than assigning to a variable.
If you think it's just weird side effects of viewing the data in a watch, which can happen with LINQ statements, then split it out into
var groups = dt.AsEnumerable().GroupBy(i => i.Field<int>("id")).ToList();
var firstOfGroups = groups.Select(i => i.First()).ToList();
and then look at groups and firstOfGroups in the debugger. Temporarily evaluating items with .ToList() can help a lot with viewing things in the debugger.
I think it is possible, can double check the count of each group items
.Select(g=>new { k = g.Key, c = g.Count() })
I have a feature class which contain property information, what I would like to do it total the value of all properties and display that in a table. The attribute table looks something like this:
ObjectId PID Value
0 1000 10,000
1 1001 25,000
2 1002 100,000
I would like to sum the value field, in order to give me a total for the entire area. So in this example, the value of all properties would be $135,000... I would like to calculate this and display it...
sounds like a pretty straight forward problem, but I can't seem to find a solution. How to do this on Xamarin forms MVVM format
Well, assuming you are using SQL then you would use something like:
select sum(count) from TableXXX where location = 'colombo'.
If you are using EF then it would be more like:
double x = dbContext.DbSet("XXX")
.Where(item => item.Location == "colombo")
.Select(item => item.Count)
.Sum();
I'm trying to recreate the following SQL query in LINQ:
select * from table where column like 'RECORD_%01'
What I have is:
var data = from t in context.table
where t.column.StartsWith("RECORD")
&& t.column.EndsWith("01")
select t;
which is equivalent to:
select * from table where column like 'RECORD%01'
Can someone help me as to how I can add the condition for '_%', not '%'?
If you guys don't know what I'm talking about with the SQL issue, please check the following image, which explains SQL.
This is what you want (or something very similar):
https://learn.microsoft.com/en-us/dotnet/api/system.data.linq.sqlclient.sqlmethods.like
LINQ2SQL LIKE Command for Phrase
This allows you to specify a LIKE statement.
var data = from t in context.table
where SqlMethods.Like(t.column, "RECORD_%01")
select t;
From this it seems like you wanted to make sure that
It starts with RECORD
It ends with 01
And there is atleast one character after RECORD before 01
In this case you can check start with, end with and also the length.
var data = from t in context.table
where t.column.StartsWith("RECORD")
&& t.column.EndsWith("01")
&& t.column.Length>=9
select t;
Here's one way:
var data = from t in context.table
where t.column.StartsWith("RECORD")
&& t.column.EndsWith("01")
&& t.column.Length > 8
select t;
This makes sure that at there is at least one character between RECORD and 01.
Of course, depending on what Query Provider you're using, you may want to simply try use the LIKE operator using SqlMethods.Like, SqlFunctions.PatIndex or one of the methods describe here.
Here is what my model looks like:
I'm trying to get the count of distinct Assesors by a certain EventId.
Here's the code I'm trying to use:
var x = db.Assessors.Select(a => (a.Assessments.Select(y => y.EventFacility.EventId == 138))).Count();
Unfortunately, I must be coding this wrong because instead of getting the expected result (a count of 9, in this case) I'm getting the wrong result: 35.
I'm wondering if someone can take a look at my LINQ statement and tell me what I'm doing wrong?
You need to use Where and Any like this:
var result = db.Assessors
.Where(a => a.Assessments.Any(y => y.EventFacility.EventId == 138));
What this is saying is that you want all Assessors that are parents of any Assessment that is related to that particular Event.
You're going about this backward, start from what you know (the event since you have it's ID) and navigate to what you want through the navigation properties.
It's impossible to tell from your schema as it includes neither the properties nor the mapping type 1:1? 1:N? Can't know from simple lines
It would probably look Something like this
var x = db.Events
.Where(ev=>ev.Id == 138)
.SelectMany(ev=>ev.EventFacilities) //(i'm assumine possibly multiple and not 1 per event, once again schema doesn't show it, if it's not the case change SelectMany to Select)
.SelectMany(ef=>ef.Assesments) // Same assumption as above
.Select(as=>as.Assessor) // Asuming otherwise here, if wrong change Select to SelectMany
.Distinct(); // Ignore duplicate assessors
Note that your question is impossible to answer as is, this is a best effort but if you want help you should give "all" the information required, not strip out what doesn't immediately seem relevant, it would've been much easier if you took an actual screenshot of your entity diagram instead of what you made up.
I have a table with a datetime2 field and I need to get all rows out of it where the date is today. Rather oddly (in my opinion but I'm sure there's a valid reason for it) if I do:
MyTable.Where(t => t.Date == DateTime.Today).ToList()
it returns nothing even though there are entires with todays date.
What am I missing here? I thought that datetime2 allowed you to query like this instead of having to use greater than and less than to specify a timeframe?
Edit
I've tried using the .Date portion of the DateTime2 representation in Linq to SQL:
MyTable.Where(t => t.Date.Date == DateTime.Today).ToList()
but I'm still getting nothing. Yet in my database there are rows with the value 2011-08-05 00:00:00.0000000 which is clearly today.
Edit again
I've ran the query:
List<string> dates = MyTable.Select(t => t.Date.Date.ToString()).ToList();
and I'm getting results like 2011-08-05, so that portion obviously works.
However, when I run
DateTime.Today.Date.ToString()
I get 08/05/2011 00:00:00. Could the addition of this time portion be causing the issue? How would I remove this?
Edit 3
Got it to work using the code:
MyTable.Where(t => t.Date.Date.ToString() == DateTime.Today.Date.ToString("yyyy-dd-MM")).ToList();
This seems hacky though (converting to a string before comparison) and surely there must be a cleaner way?
It sounds like the date in the database isn't actually today (8th May). It's probably 5th August.
It looks like your datetime2 field is called Date. You need to use the Date property of this Date field to ignore the time of day.
MyTable.Where(t => t.Date.Date == DateTime.Today).ToList()