LINQ按列x排序,如果为空则取列y

时间:2017-03-30 21:09:12

标签: c# sql linq

我正在使用以下数据模型构建一个简单的消息传递系统:

public partial class Conversation
{
    public Conversation()
    {
        this.Messages = new HashSet<Message>();
        this.Customers = new HashSet<Customer>();
        this.MessagingHubConnections = new HashSet<MessagingHubConnection>();
    }

    public int Id { get; set; }
    public int BoatId { get; set; }
    public System.DateTime TimeCreated { get; set; }

    public virtual ICollection<Message> Messages { get; set; }
    public virtual Boat Boat { get; set; }
    public virtual ICollection<Customer> Customers { get; set; }
    public virtual ICollection<MessagingHubConnection> MessagingHubConnections { get; set; }
}

public partial class Message
{
    public int Id { get; set; }
    public int ConversationId { get; set; }
    public string Text { get; set; }
    public bool IsRead { get; set; }
    public System.DateTime TimeSend { get; set; }
    public int CustomerId { get; set; }

    public virtual Conversation Conversation { get; set; }
    public virtual Customer Customer { get; set; }
}

当客户打开其帐户信息中心时,我想显示所有会话的列表。应根据以下规则对此进行排序:列表中的第一个对话是带有最新Message.TimeSent消息的对话。如果对话没有消息,则必须选择Conversation.TimeCreated。 下面的代码就是我现在所拥有的,但是当Conversation没有消息时,这显然不起作用。以下代码中的变量conversationsIQueryable<Conversation>

var orderedConversations = conversations.OrderByDescending(c => c.Messages.Max(m => m.TimeSend));

任何可以帮助我的人?​​

1 个答案:

答案 0 :(得分:2)

通过在TimeSend -ing 之前将DateTime?投射到Max(),当集合为空而不是(DateTime?)null时,您可以获得InvalidOperationException获得TimeCreated。然后,您可以使用var orderedConversations = conversations .OrderByDescending(c => c.Messages .Select<Message, DateTime?>(x => x.TimeSend) .OrderByDescending(x => x) .FirstOrDefault() ?? c.TimeCreated);

将此结果归零
subroutine FortranCall (r1, num)
    !DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE, ALIAS:"FortranCall" :: FortranCall
    integer, intent(in) :: r1
    character(10), intent(out) :: num
    !DEC$ ATTRIBUTES REFERENCE :: num

    num = ''
    write (num,'(i0)') r1 * 2

return
end subroutine FortranCall