I am inside a foreach loop of my model. For every document I need to grab a note. The note is linked by documentID in both tables. I keep only getting Note type returned instead of the actual note.
#foreach ( var item in Model.document)
{
<span>#item.Table_Note.Where(n => n.documentid == item.documentid).Select(s => s.note)</span>
}
The above just returns the object. What am I doing wrong to be able to return the specific note from the table?
Try this instead:
#item.Table_Note.FirstOrDefault(n => n.documentid == item.documentid).note
This will fix your issue.
Alternately to handle null value you could use below as well:
#(item.Table_Note.FirstOrDefault(n => n.documentid == item.documentid) ?? new Table_Note()).note
Related
Instead of doing this horrible loop which does achieve the desired result :
foreach (var mealsViewModel in mealsListCollection)
{
foreach (var VARIABLE in mealsViewModel.Items)
{
foreach (var d in VARIABLE.ArticlesAvailable)
{
d.ArticleQty = 0;
}
}
}
I'm trying to achieve the same result but with this linQ statement :
mealsListCollection.ForEach(u =>
u.Items.Select(o => o.ArticlesAvailable.Select(c =>
{
c.ArticleQty = 0;
return c;
})));
But the linQ statement does not reset ArticleQty to zero
What I am doing wrong? and why ?
Change your linq to ForEach cause Select does not iterate through collection in the way you want.
MSDN definition:-
Select Projects each element of a sequence into a new form.
ForEach Performs the specified action on each element of the List.
mealsListCollection.ForEach(u =>
u.Items.ForEach(o =>
o.ArticlesAvailable.ForEach(c =>
{
c.ArticleQty = 0;
})));
Use SelectMany to work through trees of nested lists. Use the ForEach function last to do the work:
mealsListCollection
.SelectMany(m => m.Items)
.SelectMany(i => i.ArticlesAvailable)
.ToList()
.ForEach(a => { a.ArticleQty = 0; });
What you are doing wrong is: select is returning your same collection, but has no effect until the objects are iterated over. Sitting in the foreach call, the selects are outside of the execution path. (Review comments for more information).
.select() in a call by itself does nothing special but determine what the returned list will look like.
.select().ToList() iterates over the collection, applying the projection.
If you were to set a variable equal to the .select call, but never access the data inside it, then the values would essentially still be what they started as. As soon as you iterate over, or select a specific element, it would then apply the projections.
Changing the selects to foreachs per vasily's comments will give you the desired results.
Can I perhaps suggest that you look to set the value equal to 0 further up your stack ( or down)? - Without knowing your use case, maybe there Is a better place to default it back to 0 than where you have chosen?
(automapper, Initializer, etc )
Hello I try To Convert My old code to new version with Linq but i have problem for do it
old :
foreach (var item in NetworkInterface.GetAllNetworkInterfaces())
{
if (item.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
{
lstTrace.Items.Add(item.Name);
}
}
to this:
lstTrace.Items.Add(
NetworkInterface.GetAllNetworkInterfaces()
.Where(nic => nic.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
.FirstOrDefault()
.Name
);
But it just returns one result.
How can I get all found items?
I would not recommend to create 'one-liner' code which spans for 5 lines and mixes both data selection and filling list view. Make both things easy to read and understand. Split (1) retrieving and filtering data with (2) assigning data to list view:
var ethernetInterfaceNames =
from i in NetworkInterface.GetAllNetworkInterfaces()
where i.NetworkInterfaceType == NetworkInterfaceType.Ethernet
select i.Name;
foreach(var name in ethernetInterfaceNames)
lstTrace.Items.Add(name);
I would also move getting ethernet interface names to separate method or layer. Thus you will split business logic and presentation logic. You can use AddRange here, but it willl not make your code any simpler:
lstTrace.Items.AddRange(ethernetInterfaceNames.Select(n => new ListViewItem(n)).ToArray())
I believe simple foreach loop is far more readable.
You need to use the AddRange method to add multiple items and then you just need to use select to get the Names of your nics.
Your current code is using FirstOrDefault which will only ever return a single value (the first) from your enumerable.
lstTrace.Items.AddRange(
NetworkInterface
.GetAllNetworkInterfaces()
.Where(nic => nic.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
.Select(nic => nic.Name)
.ToArray()
);
Additionally xanatos's comment on your question is worth repeating here. Your previous code worked fine, and was readable. Doing this with LINQ isn't going to make your code faster and I would probably say makes it harder to read if anything. While the above code should work I would seriously consider just keeping your original code.
lstTrace.Items.AddRange(NetworkInterface.GetAllNetworkInterfaces().Where(nic => nic.NetworkInterfaceType == NetworkInterfaceType.Ethernet).Select(a => a.Name).ToArray());
You are only getting one, because you are only asking for one: FirstOrDefault will give you the first member of the sequence or the type's default value if its empty.
What you need to do is project the sequence to what you really need using Select:
lstTrace.Items
.AddRange(NetworkInterface.GetAllNetworkInterfaces()
.Where(nic => nic.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
.Select(item => item.Name));
Here is an example on how to use AddRange
var projects = multi.Read<ProjectDto>();
var projectAct = multi.Read<ProjectActivity>();
foreach (var project in projects)
{
project.ProjectActivities = new List<ProjectActivity>();
project.ProjectActivities.AddRange(projectAct.Where(x => x.ProjectId == project.ProjectId));
}
Note: One cannot use the addrange on a data type IEnumerable only on the data type list.
Just some details. Get Records is a variable where it contains the results of my stored procedure. Now, what I want to ask is what if I want to remove the group by function but I still want to get the key and items? Is there a way to do it?
var sortResCinema = GetRecords.Where(x => test2.branch == x.Bbranch && test.movieName == x.MovieName && x.MovieName != null)
.GroupBy(x => x.MovieName,
(key, elements) =>
new
{
Id = key,
Items = elements.ToList()
}).ToList();
There's no need for GroupBy here since you are looking for a specific movieName.
I guess you wanted something like this:
var sortResCinema = GetRecords.Where(x => test2.branch == x.Bbranch && test.movieName == x.MovieName).ToList();
You can replace the GroupBy with a Select. The Select statement can be used to alter the type of the results returned, which is what you appear to want to do. Should work with exactly the same syntax as the second parameter. So replace "GroupBy" with "Select" and remove the first argument. The key and elements properties that are being used in the GroupBy statement are internal to that function so you'd need to work out what function you want to replace these by, for instance the key might be x.MovieName.
I tried to compare two ids and get some result.it works for other strings.but not for this.
I tried like this.
var neededData = mainFaires.Where(c => c.trimacid == passId );
in here passId= OX20160330HAVHAV
and in the mainFaires list, in somewhere it includes this id.but it didn't give the result.I found in here
var x = mainFaires.ElementAt(27261);
this list include the same id.but didn't give result.I can't think why.
ElementAt is find the position.
You should use select to find the records
var x = mainFaires.Select(o => o.trimacid == 27261);
You should use .ToList() .First() or .FirstOrDefault() to actually commit the query and get a result. Your code only defined the query, but didn't actually submit it to the data collection.
If you expect only one item as a result, you're code should look like this:
var neededData = mainFaires.Where(c => c.trimacid == passId ).FirstOrDefault();
If there was no item found, neededData would be NULL or whatever the default value is. You may also check the Documentation here https://msdn.microsoft.com/en-us/library/system.linq.enumerable%28v=vs.100%29.aspx
I am getting the Values from DataBase View Table using the EDM
Query as IList Type.
it is giving some Collection of Elements.
From this collection, i am tring
to filter the data based on One Column but is doesn't giving the
filtered data even though the data is present based on condition The
query is as like below.
For Getting Data form DataBase // it is
fetching some collection of data.
IList<EFModel.EntityModel.vwGetActiveEmployee> activeEmployeelist = TimeOffService.GetActiveEmployees();
Here i want to fileter the data based on Column IsManger(values 1 or 0)
For that i wrote like
IList<EFModel.EntityModel.vwGetActiveEmployee> managerlist = activeEmployeelist.Where(p => p.IsManager == 1).Select(p => p) as IList<EFModel.EntityModel.vwGetActiveEmployee>;
But here the Managerlist showing null values. When i filter the data
using below
var emplistVar = activeEmployeelist.Where(p => p.IsManager.Equals(1)).Select(p => p);
it showing the some collection of data with "var" type but if i give
Class type it showing null. What is the reason here, This data is
taken from database View Data.
This code (reformatted to avoid scrolling):
IList<EFModel.EntityModel.vwGetActiveEmployee> managerlist
= activeEmployeelist.Where(p => p.IsManager == 1)
.Select(p => p)
as IList<EFModel.EntityModel.vwGetActiveEmployee>;
... will always give managerlist as a null, as Select doesn't return an IList<T> in any implementation I've ever seen. I suspect you want:
IList<vwGetActiveEmployee> managerlist =
activeEmployeelist.Where(p => p.IsManager == 1)
.ToList();
Note that unless you're deliberately performing a reference type conversion which can validly fail (in which case you should usually be checking the result against null) you should prefer casts instead of as. If you'd used a cast here, you'd have seen an exception immediately, because the value returned by Select wasn't of the type you were expecting.