在DBQuery中按匿名类型排序

时间:2016-02-03 09:56:24

标签: c# entity-framework linq

我正在努力解决一个问题,我必须能够有效地从数据库中检索数据。

我使用的是EF 4.3 / c#。

这是我的EF逻辑,可以回收数据:

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(
                       getApplicationContext());

IEnumerable<Offer> GetHotOffers() { using (var uow = new UnitOfWork(Connection.Products)) { var r = new Repository<Offer>(uow.Context); return r.Find(o => o.OfferPopularity != null && o.OfferPopularity.TotalVotes > 5 && o.OfferPopularity.PctUpvotes >= 55) .Include(o => o.OfferPopularity) .ToList() <= this needs to be removed .OrderByDescending(o => ** an in memory method **) .Take(20) .ToList(); } } 方法是一个简单的存储库包装器 - 它返回Find()

在数据库中,我有两个数据:

  • PctUpvotes - 显示%up upvotes的十进制数字(相对于 downvotes)。两者的总和= 100。
  • TotalVotes - 投票的总票数。

从查询中可以看出,我能够在DBQuery<T>方法中稍微缩小选择范围,这意味着它在数据库中完成。

但是,我想使用不易获得的数据来订购列表,但可以假设。我决定不将它放入计算字段,因为它将可变逻辑绑定到数据库中。

这是我需要融入的逻辑,它像交通信号灯系统一样:

  • Min PctUpvotes 55%,Min TotalVotes:5 = level 1
  • Min PctUpvotes 60%,Min TotalVotes:10 = level 2
  • Min PctUpvotes 65%,Min TotalVotes:15 = level 3
  • Min PctUpvotes 70%,Min TotalVotes:20 = level 4

所以,一旦我做了基础选择,需要按级别(降序)和PctUpvotes(降序)排序。

一旦将查询转换为列表,我就可以这样做,只需在Find()之后调用linq逻辑中的方法,就像这样:

ToList()

但是,它是在内存中完成的,而不是在数据库中完成的。

我的问题是:上面的逻辑可以合并到DBQuery逻辑中,这样我就不必两次调用public static int AdjVotes(int votes, decimal pctUpvotes) { if (votes >= 20 && pctUpvotes > 70) return 4; if (votes >= 15 && pctUpvotes > 65) return 3; if (votes >= 10 && pctUpvotes > 60) return 2; return 1; } ,并且整个事情都是针对数据库运行的吗?

1 个答案:

答案 0 :(得分:1)

运算符(bool)?(trueValue):(falseValue)被编译为本机数据库查询;但它看起来有点乱:

return r.Find(o =>
  o.OfferPopularity != null &&
  o.OfferPopularity.TotalVotes > 5 && o.OfferPopularity.PctUpvotes >= 55)
  .Include(o => o.OfferPopularity)
  .OrderByDescending(o =>
    (o.OfferPopularity.TotalVotes >= 20 && o.OfferPopularity.TotalVotes > 70 ? 4 :
      (o.OfferPopularity.TotalVotes >= 15 && o.OfferPopularity.TotalVotes > 65 ? 3 :
        (o.OfferPopularity.TotalVotes >= 10 && o.OfferPopularity.TotalVotes > 60 ? 2 : 1))))
  .Take(20)
  .ToList();