我有一个现有的Windows应用程序,它会在设置的时间间隔内在屏幕上显示一条消息。从SQL Server数据库中随机选择消息,通过使用当前日期标记消息,确保每条消息仅在当天显示一次。表结构如下:
Id int
Text nvarchar
LastDateUsed datetime
我希望通过制作选择消息的逻辑来改进现有代码,以便最近使用过的消息不太可能被选中。
我现有的随机选择邮件的代码如下:
IQueryable<Message> filteredMessages = db.Messages;
var currentDate = DateTime.Today;
IQueryable<int> filteredMessageIds = filteredMessages.Where(x => x.LastDateUsed < currentDate).Select(x => x.Id);
int filteredMessagesCount = filteredMessageIds.Count();
// Select one Id
int selectedId = filteredMessageIds.ToList()[SelectRandomIndex(filteredMessagesCount)];
// Display selected message
DisplayMessage(selectedId)
private static int SelectRandomIndex(int filteredMessagesCount)
{
Random rnd = new Random();
int selectedIndex = rnd.Next(1, filteredMessagesCount - 1);
return selectedIndex;
}
答案 0 :(得分:1)
只要消息的数量和上次显示的天数不是太高,这段代码就可以了:
Random rnd = new Random();
int selectedId =
db
.Messages
.Where(x => x.LastDateUsed < DateTime.Today)
.Select(x => new { x.Id, x.LastDateUsed })
.ToArray()
.SelectMany(x =>
Enumerable.Repeat(x.Id, DateTime.Today.Subtract(x.LastDateUsed).Days))
.OrderBy(x => rnd.Next())
.Concat(new [] { -1 })
.First();
此代码的主要部分是.SelectMany(...)
。它会根据上次使用该消息后的天数为每条消息重复Id
。因此,7天前最后一次使用的消息有7倍的机会被选中一天前使用的消息。
OrderBy
有点浪费,你需要检查-1
是否没有消息,但它应该没问题。