Broken Skip method in let subquery
In my application there is an issue part that allows questions and responses. Something like (Pseudo code, as this is actually generated from Entity Framework):
class Response
{
string Author;
string Comment;
DateTime Date;
}
class Issue
{
IEnumerable<Response> Responses;
}
We have a summary page where we just want to show the last two responses. I tried a linq query like this:
from issue in db.Issue
let responses = from response in issue.Responses orderby response.Date
select new
{
Issue = issue,
Question = responses.FirstOrDefault(),
Answer = responses.Skip(1).FirstOrDefault()
}
But this gives me the error that Skip can only be used on ordered collections. I checked responses
and it was an IOrderedEnummerable. I thought maybe the problem was that it was Enumerable instead of IOrderedQueryable, and saw that this happened because issue.Response is a collection so I switched the let statement to be:
let response = from response in db.Responses where response.IssueId = issue.ID // etc.
but this did not resolve the issue (but response did become an IOrderedQueryable) so I'm not really sure why entity won't accept the skip here. If I put the skip in the let
statement, it works without problem (but then I can't get the first response). The issue seams to only occur by trying to put a portion of this statement in a variable before using it.
c# entity-framework
add a comment |
In my application there is an issue part that allows questions and responses. Something like (Pseudo code, as this is actually generated from Entity Framework):
class Response
{
string Author;
string Comment;
DateTime Date;
}
class Issue
{
IEnumerable<Response> Responses;
}
We have a summary page where we just want to show the last two responses. I tried a linq query like this:
from issue in db.Issue
let responses = from response in issue.Responses orderby response.Date
select new
{
Issue = issue,
Question = responses.FirstOrDefault(),
Answer = responses.Skip(1).FirstOrDefault()
}
But this gives me the error that Skip can only be used on ordered collections. I checked responses
and it was an IOrderedEnummerable. I thought maybe the problem was that it was Enumerable instead of IOrderedQueryable, and saw that this happened because issue.Response is a collection so I switched the let statement to be:
let response = from response in db.Responses where response.IssueId = issue.ID // etc.
but this did not resolve the issue (but response did become an IOrderedQueryable) so I'm not really sure why entity won't accept the skip here. If I put the skip in the let
statement, it works without problem (but then I can't get the first response). The issue seams to only occur by trying to put a portion of this statement in a variable before using it.
c# entity-framework
If response has 10 records Questions will have records 0-9 (10), where Answer will have records 1-9 (9). Because Skip only skips the number of records you designate, It will yield the total records minus the amount you told it to skip (not include).
– nocturns2
Nov 23 '18 at 18:43
Which is fine. Later in the code I use FirstOrDefault which will take the new first one, i.e. the second one.
– Jason
Nov 23 '18 at 18:47
I'm a little confused about whether you want records 0 & 1 or records 8 & 9 from (my previous comment). What if you were to just get the responses from the query, and then manipulate it into the Question and Answer vars outside the query?
– nocturns2
Nov 23 '18 at 19:02
I want the first and the second and I'd like to pull only those back from the database. Of course I can always just pull everything into memory and sort it there but if I'm going to do that I don't need linq. :)
– Jason
Nov 24 '18 at 11:05
You should look into sql select top and the take method.
– nocturns2
Nov 24 '18 at 19:41
add a comment |
In my application there is an issue part that allows questions and responses. Something like (Pseudo code, as this is actually generated from Entity Framework):
class Response
{
string Author;
string Comment;
DateTime Date;
}
class Issue
{
IEnumerable<Response> Responses;
}
We have a summary page where we just want to show the last two responses. I tried a linq query like this:
from issue in db.Issue
let responses = from response in issue.Responses orderby response.Date
select new
{
Issue = issue,
Question = responses.FirstOrDefault(),
Answer = responses.Skip(1).FirstOrDefault()
}
But this gives me the error that Skip can only be used on ordered collections. I checked responses
and it was an IOrderedEnummerable. I thought maybe the problem was that it was Enumerable instead of IOrderedQueryable, and saw that this happened because issue.Response is a collection so I switched the let statement to be:
let response = from response in db.Responses where response.IssueId = issue.ID // etc.
but this did not resolve the issue (but response did become an IOrderedQueryable) so I'm not really sure why entity won't accept the skip here. If I put the skip in the let
statement, it works without problem (but then I can't get the first response). The issue seams to only occur by trying to put a portion of this statement in a variable before using it.
c# entity-framework
In my application there is an issue part that allows questions and responses. Something like (Pseudo code, as this is actually generated from Entity Framework):
class Response
{
string Author;
string Comment;
DateTime Date;
}
class Issue
{
IEnumerable<Response> Responses;
}
We have a summary page where we just want to show the last two responses. I tried a linq query like this:
from issue in db.Issue
let responses = from response in issue.Responses orderby response.Date
select new
{
Issue = issue,
Question = responses.FirstOrDefault(),
Answer = responses.Skip(1).FirstOrDefault()
}
But this gives me the error that Skip can only be used on ordered collections. I checked responses
and it was an IOrderedEnummerable. I thought maybe the problem was that it was Enumerable instead of IOrderedQueryable, and saw that this happened because issue.Response is a collection so I switched the let statement to be:
let response = from response in db.Responses where response.IssueId = issue.ID // etc.
but this did not resolve the issue (but response did become an IOrderedQueryable) so I'm not really sure why entity won't accept the skip here. If I put the skip in the let
statement, it works without problem (but then I can't get the first response). The issue seams to only occur by trying to put a portion of this statement in a variable before using it.
c# entity-framework
c# entity-framework
asked Nov 23 '18 at 18:17
JasonJason
17611
17611
If response has 10 records Questions will have records 0-9 (10), where Answer will have records 1-9 (9). Because Skip only skips the number of records you designate, It will yield the total records minus the amount you told it to skip (not include).
– nocturns2
Nov 23 '18 at 18:43
Which is fine. Later in the code I use FirstOrDefault which will take the new first one, i.e. the second one.
– Jason
Nov 23 '18 at 18:47
I'm a little confused about whether you want records 0 & 1 or records 8 & 9 from (my previous comment). What if you were to just get the responses from the query, and then manipulate it into the Question and Answer vars outside the query?
– nocturns2
Nov 23 '18 at 19:02
I want the first and the second and I'd like to pull only those back from the database. Of course I can always just pull everything into memory and sort it there but if I'm going to do that I don't need linq. :)
– Jason
Nov 24 '18 at 11:05
You should look into sql select top and the take method.
– nocturns2
Nov 24 '18 at 19:41
add a comment |
If response has 10 records Questions will have records 0-9 (10), where Answer will have records 1-9 (9). Because Skip only skips the number of records you designate, It will yield the total records minus the amount you told it to skip (not include).
– nocturns2
Nov 23 '18 at 18:43
Which is fine. Later in the code I use FirstOrDefault which will take the new first one, i.e. the second one.
– Jason
Nov 23 '18 at 18:47
I'm a little confused about whether you want records 0 & 1 or records 8 & 9 from (my previous comment). What if you were to just get the responses from the query, and then manipulate it into the Question and Answer vars outside the query?
– nocturns2
Nov 23 '18 at 19:02
I want the first and the second and I'd like to pull only those back from the database. Of course I can always just pull everything into memory and sort it there but if I'm going to do that I don't need linq. :)
– Jason
Nov 24 '18 at 11:05
You should look into sql select top and the take method.
– nocturns2
Nov 24 '18 at 19:41
If response has 10 records Questions will have records 0-9 (10), where Answer will have records 1-9 (9). Because Skip only skips the number of records you designate, It will yield the total records minus the amount you told it to skip (not include).
– nocturns2
Nov 23 '18 at 18:43
If response has 10 records Questions will have records 0-9 (10), where Answer will have records 1-9 (9). Because Skip only skips the number of records you designate, It will yield the total records minus the amount you told it to skip (not include).
– nocturns2
Nov 23 '18 at 18:43
Which is fine. Later in the code I use FirstOrDefault which will take the new first one, i.e. the second one.
– Jason
Nov 23 '18 at 18:47
Which is fine. Later in the code I use FirstOrDefault which will take the new first one, i.e. the second one.
– Jason
Nov 23 '18 at 18:47
I'm a little confused about whether you want records 0 & 1 or records 8 & 9 from (my previous comment). What if you were to just get the responses from the query, and then manipulate it into the Question and Answer vars outside the query?
– nocturns2
Nov 23 '18 at 19:02
I'm a little confused about whether you want records 0 & 1 or records 8 & 9 from (my previous comment). What if you were to just get the responses from the query, and then manipulate it into the Question and Answer vars outside the query?
– nocturns2
Nov 23 '18 at 19:02
I want the first and the second and I'd like to pull only those back from the database. Of course I can always just pull everything into memory and sort it there but if I'm going to do that I don't need linq. :)
– Jason
Nov 24 '18 at 11:05
I want the first and the second and I'd like to pull only those back from the database. Of course I can always just pull everything into memory and sort it there but if I'm going to do that I don't need linq. :)
– Jason
Nov 24 '18 at 11:05
You should look into sql select top and the take method.
– nocturns2
Nov 24 '18 at 19:41
You should look into sql select top and the take method.
– nocturns2
Nov 24 '18 at 19:41
add a comment |
2 Answers
2
active
oldest
votes
The problem here is: how will/should EF translate your query into a SQL statement? There is no straightforward SQL equivalent of Skip(1). Just try to write your query in SQL and you should see what I mean.
If you want an "easy" solution, then just get all responses from the DB and identify the ones you need in code.
If you want to minimize the data being read from the DB, the solutions might range from creating a view to writing a stored procedure to changing your tables so that your tables better reflect the data model in the application.
Ok, you make a good point. Accepting this as the answer.
– Jason
Nov 24 '18 at 14:19
add a comment |
I'm not quite sure what's going on here, but wouldn't this be maybe a little simpler:
var theResponse = db.Issue.Select(i => new {
Issue = i,
Question = i.Responses.FirstOrDefault(),
Answer = i.Responses.OrderBy(r => r.Date).Skip(1).FirstOrDefault()
});
But this is also weird, because you are getting a full Issue
object with all of its properties and whatnot, including the Reponse
objects and stuffing it back into an Issue
property of your dynamic type beside all of the Response
objects...
I'm simplifying a bit. Actually the select is pulling out all the data into a Dto. And your simplification won't work for me because I need Question to be the first response sorted by Date and Answer to be the second.
– Jason
Nov 23 '18 at 19:17
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53451372%2fbroken-skip-method-in-let-subquery%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
The problem here is: how will/should EF translate your query into a SQL statement? There is no straightforward SQL equivalent of Skip(1). Just try to write your query in SQL and you should see what I mean.
If you want an "easy" solution, then just get all responses from the DB and identify the ones you need in code.
If you want to minimize the data being read from the DB, the solutions might range from creating a view to writing a stored procedure to changing your tables so that your tables better reflect the data model in the application.
Ok, you make a good point. Accepting this as the answer.
– Jason
Nov 24 '18 at 14:19
add a comment |
The problem here is: how will/should EF translate your query into a SQL statement? There is no straightforward SQL equivalent of Skip(1). Just try to write your query in SQL and you should see what I mean.
If you want an "easy" solution, then just get all responses from the DB and identify the ones you need in code.
If you want to minimize the data being read from the DB, the solutions might range from creating a view to writing a stored procedure to changing your tables so that your tables better reflect the data model in the application.
Ok, you make a good point. Accepting this as the answer.
– Jason
Nov 24 '18 at 14:19
add a comment |
The problem here is: how will/should EF translate your query into a SQL statement? There is no straightforward SQL equivalent of Skip(1). Just try to write your query in SQL and you should see what I mean.
If you want an "easy" solution, then just get all responses from the DB and identify the ones you need in code.
If you want to minimize the data being read from the DB, the solutions might range from creating a view to writing a stored procedure to changing your tables so that your tables better reflect the data model in the application.
The problem here is: how will/should EF translate your query into a SQL statement? There is no straightforward SQL equivalent of Skip(1). Just try to write your query in SQL and you should see what I mean.
If you want an "easy" solution, then just get all responses from the DB and identify the ones you need in code.
If you want to minimize the data being read from the DB, the solutions might range from creating a view to writing a stored procedure to changing your tables so that your tables better reflect the data model in the application.
answered Nov 24 '18 at 13:26
MartyMarty
1846
1846
Ok, you make a good point. Accepting this as the answer.
– Jason
Nov 24 '18 at 14:19
add a comment |
Ok, you make a good point. Accepting this as the answer.
– Jason
Nov 24 '18 at 14:19
Ok, you make a good point. Accepting this as the answer.
– Jason
Nov 24 '18 at 14:19
Ok, you make a good point. Accepting this as the answer.
– Jason
Nov 24 '18 at 14:19
add a comment |
I'm not quite sure what's going on here, but wouldn't this be maybe a little simpler:
var theResponse = db.Issue.Select(i => new {
Issue = i,
Question = i.Responses.FirstOrDefault(),
Answer = i.Responses.OrderBy(r => r.Date).Skip(1).FirstOrDefault()
});
But this is also weird, because you are getting a full Issue
object with all of its properties and whatnot, including the Reponse
objects and stuffing it back into an Issue
property of your dynamic type beside all of the Response
objects...
I'm simplifying a bit. Actually the select is pulling out all the data into a Dto. And your simplification won't work for me because I need Question to be the first response sorted by Date and Answer to be the second.
– Jason
Nov 23 '18 at 19:17
add a comment |
I'm not quite sure what's going on here, but wouldn't this be maybe a little simpler:
var theResponse = db.Issue.Select(i => new {
Issue = i,
Question = i.Responses.FirstOrDefault(),
Answer = i.Responses.OrderBy(r => r.Date).Skip(1).FirstOrDefault()
});
But this is also weird, because you are getting a full Issue
object with all of its properties and whatnot, including the Reponse
objects and stuffing it back into an Issue
property of your dynamic type beside all of the Response
objects...
I'm simplifying a bit. Actually the select is pulling out all the data into a Dto. And your simplification won't work for me because I need Question to be the first response sorted by Date and Answer to be the second.
– Jason
Nov 23 '18 at 19:17
add a comment |
I'm not quite sure what's going on here, but wouldn't this be maybe a little simpler:
var theResponse = db.Issue.Select(i => new {
Issue = i,
Question = i.Responses.FirstOrDefault(),
Answer = i.Responses.OrderBy(r => r.Date).Skip(1).FirstOrDefault()
});
But this is also weird, because you are getting a full Issue
object with all of its properties and whatnot, including the Reponse
objects and stuffing it back into an Issue
property of your dynamic type beside all of the Response
objects...
I'm not quite sure what's going on here, but wouldn't this be maybe a little simpler:
var theResponse = db.Issue.Select(i => new {
Issue = i,
Question = i.Responses.FirstOrDefault(),
Answer = i.Responses.OrderBy(r => r.Date).Skip(1).FirstOrDefault()
});
But this is also weird, because you are getting a full Issue
object with all of its properties and whatnot, including the Reponse
objects and stuffing it back into an Issue
property of your dynamic type beside all of the Response
objects...
answered Nov 23 '18 at 18:54
JonathanJonathan
2,68421629
2,68421629
I'm simplifying a bit. Actually the select is pulling out all the data into a Dto. And your simplification won't work for me because I need Question to be the first response sorted by Date and Answer to be the second.
– Jason
Nov 23 '18 at 19:17
add a comment |
I'm simplifying a bit. Actually the select is pulling out all the data into a Dto. And your simplification won't work for me because I need Question to be the first response sorted by Date and Answer to be the second.
– Jason
Nov 23 '18 at 19:17
I'm simplifying a bit. Actually the select is pulling out all the data into a Dto. And your simplification won't work for me because I need Question to be the first response sorted by Date and Answer to be the second.
– Jason
Nov 23 '18 at 19:17
I'm simplifying a bit. Actually the select is pulling out all the data into a Dto. And your simplification won't work for me because I need Question to be the first response sorted by Date and Answer to be the second.
– Jason
Nov 23 '18 at 19:17
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53451372%2fbroken-skip-method-in-let-subquery%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
If response has 10 records Questions will have records 0-9 (10), where Answer will have records 1-9 (9). Because Skip only skips the number of records you designate, It will yield the total records minus the amount you told it to skip (not include).
– nocturns2
Nov 23 '18 at 18:43
Which is fine. Later in the code I use FirstOrDefault which will take the new first one, i.e. the second one.
– Jason
Nov 23 '18 at 18:47
I'm a little confused about whether you want records 0 & 1 or records 8 & 9 from (my previous comment). What if you were to just get the responses from the query, and then manipulate it into the Question and Answer vars outside the query?
– nocturns2
Nov 23 '18 at 19:02
I want the first and the second and I'd like to pull only those back from the database. Of course I can always just pull everything into memory and sort it there but if I'm going to do that I don't need linq. :)
– Jason
Nov 24 '18 at 11:05
You should look into sql select top and the take method.
– nocturns2
Nov 24 '18 at 19:41