简体   繁体   中英

Ordering Entity Framework Query by specific Value

I have a Backgrounds table in Entity Framework for a MVC C# Webpage.

I want the user to be able to choose from the supplied backgrounds. Each background record has 3 columns:

Country | State | City

Now I want the backgrounds to first be returned where user.City = Background.City, then by User.State = Background.State, then by User.Country = Background.Country then the rest.

To add a little bit more complexity, I would prefer the order to be randomised to each user - this isnt 100% necessary but would be good to prevent alot of people from the same city choosing the same background (we can use the userId or another way to seed a fake random output that is unique to the user). I also require Paging. (meaning the Order By Function I choose will need to be constant. for that user)

My first attempt, was returning the same image many times and was:

        return DbContext.Backgrounds.Where(a => a.Deleted != true)
            .OrderBy(a => a.City.ToLower() == city.ToLower() ? 0 : 1)
            .ThenBy(a => a.State.ToLower() == state.ToLower() ? 0 : 1)
            .ThenBy(a => a.Country.ToLower() == country.ToLower() ? 0 : 1);

Any assistance would be appreciated.

So you are ok with ordering. The only thing is to randomise the output not violating (Country|State|City) ordering. You also want to have this order to be preserved for a particular user when he executes the query once again.

  1. Define BackgroundHash class:

     public class BackgroundHash { public string Hash { get; set; } public int Id { get; set; } } 
  2. userId should be used as a seed for a MD5 sql hashing function. The query may be look like this

     var sql = @"SELECT CONVERT(NVARCHAR(32), HashBytes('MD5', @userId + cast(Id as nvarchar(20))), 2) as Hash, Id from Backgrounds"; return DbContext.Database.SqlQuery<BackgroundHash>(sql, new SqlParameter("userId", userId.ToString())) .Join(DbContext.Backgrounds.Where(a => a.Deleted != true), ou => ou.Id, i => i.Id, (hs, b) => new { hs, b }) .OrderBy(p => pbCity.ToLower() == city.ToLower() ? 0 : 1) .ThenBy(p => pbState.ToLower() == state.ToLower() ? 0 : 1) .ThenBy(p => pbCountry.ToLower() == country.ToLower() ? 0 : 1) .ThenBy(p => p.hs.Hash); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM