public class HomeController : Controller
{
public ActionResult Index()
{
IEnumerable<SelectListItem> ts = (from s in Enumerable.Range(1, 10)
select new SelectListItem
{
Text = s.ToString(),
Value = s.ToString(),
}).ToList(); //should use this, if I don't use this,it will output "==no choice" to the page, why?
ts.First().Selected = true;
return View(ts);
}
}
You see that if I don't use ToList,"No Choice" will be shown;otherwises it render a right value,Why?!
public ActionResult Index()
{
IEnumerable<SelectListItem> ts = (from s in Enumerable.Range(1, 10)
select new SelectListItem
{
Text = s.ToString(),
Value = s.ToString(),
});
ts.First().Selected = true;
return View(ts);
}
public ActionResult Index()
{
IEnumerable<SelectListItem> ts = (from s in Enumerable.Range(1, 10)
select new SelectListItem
{
Text = s.ToString(),
Value = s.ToString(),
});
ts.First().Selected = true;
return View(ts);
}
Hope it can help.
Sorry this is just the codes I wrote, but it didn't work……:(
Without .ToList() your ts variable represents a query which will be evaluated when it is enumerated. Prior to enumeration, it's just an expression and does not contain real data. Every time you enumerate it, the query will be re-evaluated. This is the key.
Now, look at how you are setting the Selected property:
ts.First().Selected = true;
Here, you ARE eveluating you query. You get the 1st SelectListItem from the sequence and mark it as selected. Later, when your view receives its model, it starts enumeration -- all over again. Which means, the 1st SelectListItem is ANOTHER SelectListItem,
not the same you have marked as selected. That one is gone by now.
And in the case when you call ToList(), the collection is enumerated and the result of enumeration is passed to the view. In this case the both 1st SelectListItems will match.
Marked as answer by TimoYang on Jun 05, 2012 02:00 AM
It is because LINQtoSQL uses Deferred Execution. It means that the evaluation of an expression is delayed until its realized value is actually required. Deferred execution can greatly improve performance
when you have to manipulate large data collections, especially in programs that contain a series of chained queries or manipulations. In the best case, deferred execution enables only a single iteration through the source collection.
When you Call the ToList() method on the expression. It returns the result of the expression immediatly. So you must call such a method.
in linq, the query is executed when you call the iterator (perform the for each). as explained above, each time you iterate it you get a new collection and if the linq query creates a new select object, then new objects in the colleciton.
You can set a breakpoint at this line IEnumerable <SelectListItem> ts, you will find if you add the ToList(), the ts type will be a list. If without ToList(), its type is Iterator. .First().Selected only works for list, it is not avaliable for iterator,
so if you want it work, you should add ToList() at the end of Linq.
Hope this helpful
Regards
Please mark the replies as answers if they help or unmark if not.
Feedback to us
If without ToList(), its type is Iterator. .First().Selected only works for list, it is not avaliable for iterator
Are you sure? Dear Yang yang:-)
VERY GLAD TO SEE YOU HERE AGAIN!!!!!!!!!!!!
I've decompiled the codes for first in reflector, and the codes are——
[__DynamicallyInvokable]
public static TSource First<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
IList<TSource> list = source as IList<TSource>;
if (list != null)
{
if (list.Count > 0)
{
return list[0];
}
}
else
{
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
if (enumerator.MoveNext())
{
return enumerator.Current; //Attention here!
}
}
}
throw Error.NoElements();
}
Please notice the bold one——it will return you the Current suitable instance——and the instance should be type of REFER……So any changes to the referred type should change its own value. So I'm afraid yours isn't right.
I tend to believe it that each time when you use First() or something like this, it will render to do query to the L2S or L2O again to generate new object collection. But not very sure……:(
TimoYang
Contributor
3732 Points
1275 Posts
Why it cannot work property without "ToList"?
Jun 03, 2012 09:07 AM|LINK
In an MVC app——Here's my View:
@{ Layout = "~/Views/Shared/_Layout.cshtml"; } <!DOCTYPE html> <html> <head> <title>Index</title> </head> <body> <div> @section A { @Html.DropDownList("Dropdownlist_Name",Model as IEnumerable<SelectListItem>,"==No choice==") } </div>n </body> </html>[Controller]
public class HomeController : Controller { public ActionResult Index() { IEnumerable<SelectListItem> ts = (from s in Enumerable.Range(1, 10) select new SelectListItem { Text = s.ToString(), Value = s.ToString(), }).ToList(); //should use this, if I don't use this,it will output "==no choice" to the page, why? ts.First().Selected = true; return View(ts); } }You see that if I don't use ToList,"No Choice" will be shown;otherwises it render a right value,Why?!
jsiahaan
Contributor
2550 Points
645 Posts
Re: Why it cannot work property without "ToList"?
Jun 03, 2012 09:37 AM|LINK
Hi
Try this:
or like this:
public ActionResult Index() { IEnumerable<SelectListItem> ts = (from s in Enumerable.Range(1, 10) select new SelectListItem { Text = s.ToString(), Value = s.ToString(), }); ts.First().Selected = true; return View(ts); }Hope it can help.
Indonesian Humanitarian Foundation
TimoYang
Contributor
3732 Points
1275 Posts
Re: Why it cannot work property without "ToList"?
Jun 03, 2012 09:38 AM|LINK
I know such a solution,but why I cannot omit it?
Thx anyway!:-)
TimoYang
Contributor
3732 Points
1275 Posts
Re: Why it cannot work property without "ToList"?
Jun 03, 2012 09:43 AM|LINK
Sorry this is just the codes I wrote, but it didn't work……:(
m1kael
Member
56 Points
8 Posts
Re: Why it cannot work property without "ToList"?
Jun 03, 2012 01:27 PM|LINK
Without .ToList() your ts variable represents a query which will be evaluated when it is enumerated. Prior to enumeration, it's just an expression and does not contain real data. Every time you enumerate it, the query will be re-evaluated. This is the key.
Now, look at how you are setting the Selected property:
Here, you ARE eveluating you query. You get the 1st SelectListItem from the sequence and mark it as selected. Later, when your view receives its model, it starts enumeration -- all over again. Which means, the 1st SelectListItem is ANOTHER SelectListItem, not the same you have marked as selected. That one is gone by now.
And in the case when you call ToList(), the collection is enumerated and the result of enumeration is passed to the view. In this case the both 1st SelectListItems will match.
kshyju
Member
134 Points
39 Posts
Re: Why it cannot work property without "ToList"?
Jun 03, 2012 02:00 PM|LINK
It is because LINQtoSQL uses Deferred Execution. It means that the evaluation of an expression is delayed until its realized value is actually required. Deferred execution can greatly improve performance when you have to manipulate large data collections, especially in programs that contain a series of chained queries or manipulations. In the best case, deferred execution enables only a single iteration through the source collection.
When you Call the ToList() method on the expression. It returns the result of the expression immediatly. So you must call such a method.
My flarack profile
TimoYang
Contributor
3732 Points
1275 Posts
Re: Why it cannot work property without "ToList"?
Jun 04, 2012 01:51 AM|LINK
Hey all:)
It seems that your meaning is——L2S will only fetch values when it's needed?But my codes above is a L2O instead od L2S, is it the same function?
bruce (sqlwo...
All-Star
37626 Points
5574 Posts
Re: Why it cannot work property without "ToList"?
Jun 04, 2012 04:42 AM|LINK
in linq, the query is executed when you call the iterator (perform the for each). as explained above, each time you iterate it you get a new collection and if the linq query creates a new select object, then new objects in the colleciton.
Young Yang -...
All-Star
21740 Points
1825 Posts
Microsoft
Re: Why it cannot work property without "ToList"?
Jun 04, 2012 07:09 AM|LINK
Hi
You can set a breakpoint at this line IEnumerable <SelectListItem> ts, you will find if you add the ToList(), the ts type will be a list. If without ToList(), its type is Iterator. .First().Selected only works for list, it is not avaliable for iterator, so if you want it work, you should add ToList() at the end of Linq.
Hope this helpful
Regards
Feedback to us
Develop and promote your apps in Windows Store
TimoYang
Contributor
3732 Points
1275 Posts
Re: Why it cannot work property without "ToList"?
Jun 04, 2012 07:40 AM|LINK
Are you sure? Dear Yang yang:-)
VERY GLAD TO SEE YOU HERE AGAIN!!!!!!!!!!!!
I've decompiled the codes for first in reflector, and the codes are——
[__DynamicallyInvokable] public static TSource First<TSource>(this IEnumerable<TSource> source) { if (source == null) { throw Error.ArgumentNull("source"); } IList<TSource> list = source as IList<TSource>; if (list != null) { if (list.Count > 0) { return list[0]; } } else { using (IEnumerator<TSource> enumerator = source.GetEnumerator()) { if (enumerator.MoveNext()) { return enumerator.Current; //Attention here! } } } throw Error.NoElements(); }Please notice the bold one——it will return you the Current suitable instance——and the instance should be type of REFER……So any changes to the referred type should change its own value. So I'm afraid yours isn't right.
I tend to believe it that each time when you use First() or something like this, it will render to do query to the L2S or L2O again to generate new object collection. But not very sure……:(
Is that so?
If yes,
m1kael,
kshyju
and
bruce (sqlwo...
are all right!
Waiting for a full-trusted reason……
:D