Reputation: 14243
I have list of Books
with PK of Id
and some of Books
may deleted.
for example list with this Id
s:
1 2 5 6 8
now I need a linq statement to return next insertion Id (in example "3")
I tried this code but it always return
"1":
public int GetNextRecordId()
{
List<Book> books = getAll();
int counted = books.Count();
foreach (Book b in books)
{
if (books.Where(book => book.Id == (b.Id + 1)) == null)
return b.Id + 1;
}
return 1;
}
How to fix this?
Upvotes: 1
Views: 817
Reputation: 39277
If you have a large number of books you probably can't hold them all in memory like that. And you certainly don't want to be doing a loop over them with a Where
clause in it iterating over them again. You would be better off reading them sequentially to look for a gap like this:-
public int GetNextRecordId()
{
// Cannot load all books into memory ...
IEnumerable<Book> books = dataContext.Books.OrderBy(b => b.Id);
int index = 0;
foreach (var book in books)
{
index++;
if (index < book.Id) return index;
}
return index;
}
Upvotes: 2
Reputation: 4907
I suggest this linq query, if this query run on linq to entites, cost of query is very low:
var id = books.Select(p => p.Id + 1).Except(books.Select(p=>p.Id)).First();
Upvotes: 1
Reputation: 4156
One thing I notice right away is that this will never be true:
books.Where(book => book.Id == (b.Id + 1)) == null
The Where call returns an empty enumerable if it finds no matches. Start from there.
Try this instead:
!books.Where(book => book.Id == (b.Id + 1)).Any()
Upvotes: 5