I asked this question earlier and that helped a lot. Then I realized I also need a list of IDs of the List that is a property in that object. Basically I want to end up with a list of integers generated from each list in those objects. Any ideas?
Thanks!
var ids = (from x in outerList
from y in x.List
select y).ToList();
Or to avoid dups:
var ids = (from x in outerList
from y in x.List
select y).Distinct().ToList();
For info, this could also be written:
var ids = outerList.SelectMany(x => x.List).ToList();
or:
var ids = outerList.SelectMany(x => x.List).Distinct().ToList();
Related
I'm trying to convert a SQL expression to Linq but I can't make it work, does anyone help?
SELECT
COUNT(descricaoFamiliaNovo) as quantidades
FROM VeiculoComSeminovo
group by descricaoFamiliaNovo
I try this:
ViewBag.familiasCount = db.VeiculoComSeminovo.GroupBy(a => a.descricaoFamiliaNovo).Count();
I need to know how many times each value repeats, but this way it shows me how many distinct values there are in the column.
You can try:
var list = from a in db.VeiculoComSeminovo
group a by a.descricaoFamiliaNovo into g
select new ViewBag{
familiasCount=g.Count()
};
or
var list = db.VeiculoComSeminovo.GroupBy(a => a.descricaoFamiliaNovo)
.Select (g => new ViewBag
{
familiasCount=g.Count()
});
If you need column value:
new ViewBag{
FieldName=g.Key,
familiasCount=g.Count()
};
You don't need the GROUP BY unless there are fields other than the one in COUNT. Try
SELECT
COUNT(descricaoFamiliaNovo) as quantidades
FROM VeiculoComSeminovo
UPDATE, from your comment:
SELECT
COUNT(descricaoFamiliaNovo) as quantidades,
descricaoFamiliaNovo
FROM VeiculoComSeminovo
GROUP BY descricaoFamiliaNovo
That's it as SQL. In LINQ it is something like:
var reponse = db.VeiculoComSeminovo.GroupBy(a => a.descricaoFamiliaNovo)
.Select ( n => new
{Name = n.key,
Count = n.Count()
}
)
Not tested.
Ty all for the help.
I solved the problem using this lines:
// get the objects on db
var list = db.VeiculoComSeminovo.ToList();
// lists to recive data
List<int> totaisFamilia = new List<int>();
List<int> totaisFamiliaComSN = new List<int>();
// loop to cycle through objects and add the values I need to their lists
foreach (var item in ViewBag.familias)
{
totaisFamilia.Add(list.Count(a => a.descricaoFamiliaNovo == item && a.valorSeminovo == null));
totaisFamiliaComSN.Add(list.Count(a => a.descricaoFamiliaNovo == item && a.valorSeminovo != null));
}
The query was a little slow than I expected, but I got the data
I used linq to create a list of IO_EQUATIONS. An IO_EQUATION consists of a single OUTPUT_POINT and a List of INPUT_POINT. INPUT_POINT and OUTPUT_POINT have a common x, y, and z coordinate but they contain other fields that are not common. I want to flatten out the List of IO_EQUATIONS to either an anonymous type or a specific point type (x, y, and z only) so that I see the Output followed by all the inputs for each IO_EQUATION in a list.
I was able to use linq to list all the OUTPUT_POINTS using the following code. list41 is the list of IO_EQUATIONS
var flat = (from d2 in list41
select (new BINARY_IO()
{
propX = d2.propOutputPoint.propX,
propY = d2.propOutputPoint.propY,
propZ = d2.propOutputPoint.propZ,
propDir = POINT_DIRECTION_Types.Output,
})).ToList();
I was able to use linq to list all the INPUT_POINTS using the following code.
list41 is the list of IO_EQUATIONS. propIOPointList is my list of INPUT_POINT
var flat = (from d2 in list41
from d3 in d2.propIOPointList
select (new BINARY_IO()
{
propX = d3.propX,
propY = d3.propY,
propZ = d3.propZ,
propDir = POINT_DIRECTION_Types.Input,
})).ToList();
I can get the information separately by I want the data to be formatted as an output followed by the inputs, then the next output followed by the inputs, etc.
I have a feeling this is really simple and I just can't get it to work.
Thanks
To flatten a list of list in LINQ, use .SelectMany
var flattenedList = list1.SelectMany(i => i.PropertyThatIsAList)
Many similar questions, for example :
Flatten List in LINQ
The easiest way is to transform each item in list41 into an IEnumerable<BINARY_IO> in the order you listed, then using SelectMany to flatten the resulting IEnumerable<IEnumerable<BINARY_IO>>.
var flat =
(from d2 in list41
select
Enumerable.Repeat(
new BINARY_IO {
propX = d2.propOutputPoint.propX,
propY = d2.propOutputPoint.propY,
propZ = d2.propOutputPoint.propZ,
propDir = POINT_DIRECTION_Types.Output}, 1)
.Concat(
from d3 in d2.propIOPointList
select new BINARY_IO {
propX = d3.propX,
propY = d3.propY,
propZ = d3.propZ,
propDir = POINT_DIRECTION_Types.Input}))
.SelectMany(i => i)
.ToList();
Note that I use Enumerable.Repeat(v, 1) to get a singleton, there are other methods as well.
Additionally you could inline the call to SelectMany but at that point you might want to switch away from query syntax and just use a manual call to Select for the second from/select.
In the past, i was reading data from one excel sheet named "On leave" and do operation on the result like this:
var resultNew1 = (from x in dataNew.Worksheet<Employee>("On Leave")
select x).ToList();
but now I have got another sheet which is "Working". so I did this:
var resultNew1 = (from x in dataNew.Worksheet<Employee>("On Leave")
select x);
var resultNew2 = (from x in dataNew.Worksheet<Employee>("Working")
select x);
please notice that the first one was ToList()
but now I didn't make ToLists() because I want to ask you if there is a way to store these two vars which are resultsNew1 and resultsNew2 in one var and then make that var ToList()
If you need more infomration, please tell me
You can use Concat
var employees = dataNew.Worksheet<Employee>("On Leave")
.Concat(dataNew.Worksheet<Employee>("Working"))
.ToList();
You can use List<T>.AddRange:
List<Employee> employees = new List<Employee>();
employees.AddRange(resultNew1);
employees.AddRange(resultNew2);
I originally have 2 Lists for Keynotes and Tracks. Each of which were then Grouped By date through a Key. See below:
var Keynotes = _keynoteService.GetKeynotesForContentItem(trackPart.ContentItem).GroupBy(k => string.Format("{0}-{1}", k.Timeslot.DayOfYear, k.Timeslot.Year));
var Tracks = GetTracksForContentItem(trackPart.ContentItem);
foreach (var track in Tracks)
{
var trackItem = new TrackItem();
trackItem.Days = new List<TrackDay>();
var trackDays = track.Sessions.GroupBy(s => string.Format("{0}-{1}", s.Timeslot.DayOfYear, s.Timeslot.Year));
foreach(var trackDay in trackDays)
{
var trackKey = trackDay.Key //THIS IS THE KEY I NEED TO MATCH IN Keynotes
var trackKeynotes = Keynotes. //I'm Stuck here
The new lists are now Keynotes and trackDays which are actually lists of lists by Date Keys.
How do I select a list within Keynotes that matches a specific key from trackDays? I already have the key, I just need to know how to select from Keynotes properly to get the right list.
I'm not a LINQ expert so I'd like some help.
I was thinking Keynotes.Select or Keynotes.SingleOrDefault
Any piece of advise would be highly appreciated. Thanks!
var trackKeynotes = Keynotes.SingleOrDefault(g => g.Key == trackKey);
You should do it like this
var result = (from x in Keynotes
join td in TrackDays on x.Key equals td.Key
select x).ToList();
Use Keynotes[trackKey] to index into your grouped items.
Try this instead ::
var trackKeynotes = Keynotes.Where(K => K.Key == trackKey);
Hope this will help !!
Maybe this
var trackKeynotes = Keynotes.Where(x => x.Key == trackKey);
I assume that trackKey is a key of Keynotes.
I have the following query that receives a list of IDs and I want to do a count. There's also an object model CountModel that holds the counts with each property defined as an int.
public class GetCountByStatus(List<int> TheIDs)
{
...using MyDC...
var CountData = (from d in MyDC.Data
where TheIDs.Contains(d.ID)
group d by d.Status into statusgroup
select new CountModel()
{
CountStatus1 = (from g in statusgroup
where g.Status == 1
select g).Count(),
CountStatus2 = (from g in statusgroup
where g.Status == 2
select g).Count(),
CountStatusN = ....
}).Single();
If for instance there are no elements with status N, will this code crash or will the count be 0 for CountStatusN ? Is this the best way to do what I want?
Thanks.
I would go for a dictionary instead, try something like this:
var countData = MyDC.Data.Where(y => TheIDs.Contains(y.ID))
.GroupBy(y => y.Status).ToDictionary(y => y.Key, y => y.Count());
I haven't tried it my self and not written the code in VS, but I think that is almost how you do can do it. That will give you a dictionary where the key is the status and the value is the count of that status.
Defining a model with properties named SomethingX is not very flexible. That means you have to go in an change the model when there is a new status. Keeping the data in the dictionary instead will save you from that.
Count() will always return an integer, which is 0 if there are no elements with the given status. Therefore CountStatusN will always be an integer as well.