0

受信したメッセージを NHibernate を使用してデータベースに保存しようとしています。ただし、同じメッセージが 2 回受信される可能性があり、その場合、重複をデータベースに保存したくありません。私が最初に考えたのは、次のことを行うことでした。

// in SaveRange(IEnumerable<Message> messages
var alreadyStoredMessages = session.Query<Message>().Intersect(messages);

var newMessages = messages.Except(alreadyStoredMessages);

ただし、NHibernate は Intersect をサポートしていないようで、例外が発生します。いつでもすべてのメッセージをフェッチし、それらをリストまたは配列に変換してから交差を実行できることはわかっていますが、あまり効果的ではありません。

Message クラスは IEquatable を実装し、GetHashCode() と Equals(object obj) もオーバーライドします。等価性は、いくつかのプロパティ (タイムスタンプ、いくつかの文字列など) に依存します。

4

1 に答える 1

1

すべての新しいメッセージが一度に届く場合は、フィルターを使用します。

var alreadyStoredMessages = session.QueryOver<Message>()
    .WhereRestrictionOn(m => m.timestamp).In(messages.Select(m => m.timeStamp))
    .AsEnumerable()
    .Intersect(messages);

var newMessages = messages.Except(alreadyStoredMessages).ToList();

重複するメッセージが次々と続くと仮定します。最後に受信したn個のメッセージのバッファを保持し、それらを調べます。

var lastMessages = new Queue<Message>(100);
while(true)
{
    var message = GetNextMessage();
    if (!lastMessages.Contains(message))
    {
        lastMessages.Enqueue(message);
        session.Save(message);
        if (lastMessages.Count >= 100);
            lastMessages.Dequeue();
    }
}
于 2012-10-19T11:58:24.343 に答える