按特定值排序实体框架查询

时间:2017-03-13 14:30:31

标签: c# sql entity-framework

我在MVC C#网页的实体框架中有一个Backgrounds表。

我希望用户能够从提供的背景中进行选择。每个背景记录有3列:

Country | State | City

现在我希望首先返回背景,其中user.City = Background.City,然后是User.State = Background.State,然后是User.Country = Background.Country,然后是其余的。

为了增加一点点复杂性,我希望将订单随机化到每个用户 - 这不是100%必要但是可以防止来自同一城市的很多人选择相同的背景(我们可以使用userId或另一种播放用户唯一的伪随机输出的方法。我还要求分页。 (意思是我选择的按功能排序需要为该用户保持不变)

我的第一次尝试是多次返回相同的图像并且是:

        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);

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:0)

所以你可以订购。唯一的办法是随机输出不违反(Country|State|City)排序的输出。您还希望在再次执行查询时为特定用户保留此顺序。

  1. 定义BackgroundHash类:

    public class BackgroundHash
    {
        public string Hash { get; set; }
        public int Id { get; set; }
    }
    
  2. userId应该用作MD5 sql散列函数的种子。查询可能看起来像这样

    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 => p.b.City.ToLower() == city.ToLower() ? 0 : 1)
        .ThenBy(p => p.b.State.ToLower() == state.ToLower() ? 0 : 1)
        .ThenBy(p => p.b.Country.ToLower() == country.ToLower() ? 0 : 1)
        .ThenBy(p => p.hs.Hash);