Linq查询基于prioirty电子邮件
我有这将有电子邮件,然后收件人表将有电子邮件Linq查询基于prioirty电子邮件
的收件人EmailMessage
标识
内容
电子邮件消息表Priority
MessageRecipient
EmailMessageFk
RecipientEmailId
LastError
LastTriedAt
NextTryAt
每个消息可具有1至10个优先其中1是最低和10是最高的。我在C#中创建了一个函数,它将在一定的时间间隔后尝试重新发送所有未决的电子邮件消息。
我想编写能在数据库上运行,并且将根据以下标准
返回最符合条件的记录单LINQ查询a)如果任何邮件收件人已经过去一直是试图在此之前发送12小时它应该是电子邮件
b)如果根据(a)标准没有找到收件人,那么它应该返回具有最高优先级的电子邮件消息,并且如果有多个具有最高优先级的电子邮件消息,则它应该返回具有最高优先级和最低LastTriedAt日期时间的消息。
请记住,我只想要一个LINQ查询,以满足所有这些要求
我用下面的查询
entities.EmailMessageRecipients.Where(
p => p.NextAttemptAt <= DateTime.UtcNow)
.Select(p => p.Message)
.Distinct()
.OrderByDescending(p => p.Priority)
.ThenBy(p => p.Id)
.FirstOrDefault();
但这个查询有一个缺陷。如果很多高优先级的消息被卡在表中,那么它将不会尝试先前的低优先级消息。
如果你想检索一个EmailMessage
实体,那么你应该查询EmailMessages
而不是EmailMessageRecipients
。如果你想要收件人,那么你可以拨打Include
。至于查询,如果我正确地解释你的条件那么你的第一个查询应该是这样的:
entities.EmailMessages.Where(em => em.EmailMessageRecipients.Any(emr => emr.NextAttemptAt <= DateTime.UtcNow.AddHours(-12))
.OrderBy(em => em.LastTriedAt)
.FirstOrDefault()
这将得到一个消息,至少有一个收件人,其NextAttemptAt
为至少12小时前,如果有是一个。如果有多个匹配,则会得到最老的LastTriedAt
值。如果返回null
,则可以通过Priority
进行查询。
,但正如我在问题中所说的,如果没有找到nextattemptat> 12小时的消息,那么会得到一个具有最高优先级的待处理消息。这种情况不包括 – yrahman
是的,正如我在答案中所说的,如果我提供的查询返回'null',那么您将通过'Priority'进行第二个查询。事实上,你认为一个单一的查询是一个好主意并不意味着它是。 – jmcilhinney
@yrahman,在一个查询中没有机会实现这一点 –
您不仅需要对NextAttemptAt进行过滤(Where),还要对NextAttemptAt进行排序(OrderBy)。 –
但我不能过滤nextattemptat,因为我需要一个带有nextattemptat> 12小时的消息,如果没有这样的消息存在,那么会得到一个最高优先级的待处理消息 – yrahman
“请记住,我只想要一个linq查询来满足所有这些要求。你想要什么和适合什么不一定是同一件事。 – jmcilhinney