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.
Define BackgroundHash
class:
public class BackgroundHash { public string Hash { get; set; } public int Id { get; set; } }
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.