score:0
I don't recommend that you write the more complex linq query to solve it.
Yes, it's becoming shorter that way but also becoming harder to read. The longer answer below. You can shorten it by yourself.
First you should get the ones which have genreIds of subGenereIds list.
var onesWithGenreIdFromList = (from bk in bookContext.Books
where subGenereIds.Contains(bk.genreId).orderby bk.Id descending select bk).ToList();
Then get the rest of the list (ones don't have genreId of subGenereIds list) from your list.
var results = (from bk in bookContext.Books
where !subGenereIds.Contains(bk.genreId)
orderby bk.id descending
select bk).ToList();
As the last step you should add the first list to second one to create the order you would like:
onesWithGenreIdFromList.AddRange(results);
var lastResults = onesWithGenreIdFromList;
Happy coding!
score:1
You'll need to to the ordering in-memory since there's not a way to pass that ordering logic to SQL. You can do that by using AsEnumerable()
to change the context from a SQL query to an in-memory query:
var results = bookContext.Books
.AsEnumerable()
.OrderByDescending(bk => bk.Id)
.ThenBy(bk => subGenereIds.IndexOf(bk.Id));
score:1
From your comments it looks like you need to have as much of this as possible done in the the database. Assuming that you have the books and the user subscriptions stored in the same place you can combine the query for the user's preferences with the search of the book table to get the result you're after.
For the sake of argument, let's assume you have some tables that look something like this as POCOs:
[Table("Books")]
public class Book
{
public int ID { get; set; }
public int Genre { get; set; }
public string Name { get; set; }
public string Author { get; set; }
public Date PublishDate { get; set; }
}
[Table("Genres")]
public class Genre
{
public int ID { get; set; }
public string Name { get; set; }
}
[Table("Users")]
public class User
{
public int ID { get; set; }
public string Name { get; set; }
}
[Table("UserGenrePreferences")]
public class UserGenrePreference
{
public int User { get; set; }
public int Genre { get; set; }
}
For the sake of the example we have one genre per book and no duplicates in the UserGenrePreferences
table.
The basic ordering might look something like this:
// get genre preferences for the selected user
var userPrefs =
from pref in context.UserGenrePReferences
where pref.User == userID
select new { Genre = (int?)pref.Genre };
var result =
from book in context.Books
join pref in userPrefs on book.Genre equals pref.Genre
into prefTemp
from pref in prefTemp.DefaultIfEmpty()
orderby (pref.Genre == null ? 1 : 0), book.ID
select book;
This does an outer join against the user's genre preferences. Books with a matching genre will have a non-null value in the matching pref
record, so they will be placed before unmatched books in the result. Pagination would then by handled by the normal .Skip(...).Take(...)
method.
For very large data sets this will still take some time to run. If you're expecting that the user will be paging through the data it might be a good idea to grab just the book IDs and cache those in memory. Take the first few thousand results and look for more when needed for instance. Then grab the book records when the user wants them, which will be much quicker than running the query above for every page.
If on the other hand your user preference data is not in the same database, you might be able to use the Contains
method to do your ordering.
Assuming that you have an array of genre IDs in memory only you should be able to do this:
int[] userPrefs = new int[] { 1, 2, 3, 5 };
var result =
from book in context.Books
orderby (userPrefs.Contains(book.Genre) ? 0 : 1), book.ID
select book;
Depending on the ORM this will translate into something similar to:
SELECT *
FROM Books
ORDER BY
CASE WHEN Genre = 1 OR Genre = 2 OR Genre = 3 OR Genre = 5 THEN 0 ELSE 1 END,
ID
This can be fairly quick but if the list of preferences is very large it could be slower.
Source: stackoverflow.com
Related Query
- Using external list to order a linq query
- Filter LINQ query using items from an external list with Lambda
- How to set order of IQueryable query based on another list using linq in c#?
- Using Linq query inside List<T>.AddRange to conditionally add elements from one list to another
- Entity Framework Linq Query to List - Error when using contains: Only primitive types, enumeration types and entity types are supported
- Linq query using list or array of ids
- Order of List using Linq is not the same as sort
- Query in returning Objects from List using LINQ
- How can I write the following code more elegantly using LINQ query syntax?
- LINQ query returns old results when source list is re-initialized
- Check if List is not null when using "contains" in LINQ query else select all records
- LINQ query using list of objects property of an object
- IN query using LINQ for IEnumerable List of items
- Linq sub query when using a repository pattern with EF code first
- Using LINQ to order a list using an existing array
- Using LINQ query result for data source for GridControl c#
- Using list in a model value in LINQ query
- Order a list of lists in C# using LINQ
- How to return list from linq query using viewmodels
- How to order list in custom Item class with linq query
- How can I check the number of calls to the database in LINQ query when using .NET Core and Code First?
- How to integrate external list to raw sql query join as table in a linq raw sql query
- Joining Two list using LINQ Query and displaying only relevant data
- Linq order by using query expression
- combine two list and linq query to order by two different fields from different lists
- LINQ query in C# using string on the fly to ORDER data
- Linq query to order a list based on date and get distinct
- How do I create a linq query that returns the distinct 3 letter prefix of words in a list using deferred execution
- Linq query list contains a list with same order
- Unable to form the proper Linq query using an "IN" list
More Query from same tag
- Use select() instead of foreach loop
- Moving Dropdown DataFieldCategory to bottom of list
- LINQ to SQL: DataContext changes are not reflected unless SubmitChanges is called
- Linq query: does this array contain this string?
- Is it possible to join an unrelated table in an EF Core Include query
- C#/Linq: Where X is Y?
- Multiple Null Foreign keys group join error in Linq
- Dynamic Linq - Joining a table with 1 to many relationship
- LINQ counting unique strings in a list and storing the values in a tuple
- automapper Missing type map configuration or unsupported mapping.?
- How do I create a dynamic Linq query to fill an ASP.NET databound ListView?
- MVC 5 ASP.NET IEnumerable<Item> does not contain a definition for "Inspection" and no extension method "inspection" accepting a first argument of type
- Linq method based left join with multiple criteria
- How can you tell if an Xnode is of XElement type?
- Linq query to return a flatened list of parent child
- SQL Query to LINQ Query Syntax
- Left join selecting with linq and a condition
- Design pattern for filtering/counting a collection in various states/steps
- LINQ Next Item in List
- Convert T-sql to Linq or Entityframework and not to use SqlQuery() for raw queries
- Remove From Duplicate Starting Names From List Linq
- Using XDocument to figure out if an element exists with a specific attribute?
- Linq Empty String vs. Space
- Creating a new ObservableCollection using a collection of classes
- Why is IQueryable twice as fast than IEnumerable when using Linq To Objects
- Find all items where child collection doesn't contain an item
- How to make Include specific field in IList in MongoDbDriver
- LINQ grouping by nullable child and parent
- Finding an item in a complex object
- Query Object Structure using string input