I'm working on an application that reads emails, extracts data from them and prints them in DataGrid
(as alerts or notifications). The data is stored in a DB.
Here's the scenario:
A new email with data arrives, if a new alert does not arrive within a specific time slot(say within 5 minutes) from the same customer, with the opposite result(e.g. 1st alert was FAIL, 2nd SUCCESS => negation), the alert in the Datagrid
is just updated.
Where is my problem: In the part where I want to update the alert, a new alert is added, which causes a duplicate and the table is confused. And it does not update when new negation alert arrives.
NOTICE: My application is larger, to better demonstrate my problem, the example is in the consol application. But with a few modifications, the code is the same
Here is my code:
Method, which read and extract data
public void MailKitLib(EmailParser emailParser)
{
using (var client = new ImapClient())
{
using (var cancel = new CancellationTokenSource())
{
client.Connect(emailParser.ServerName, emailParser.Port, emailParser.isSSLuse,
cancel.Token);
client.Authenticate(emailParser.Username, emailParser.Password, cancel.Token);
var inbox = client.Inbox;
inbox.Open(FolderAccess.ReadOnly, cancel.Token);
Console.WriteLine("Total messages: {0}", inbox.Count);
Console.WriteLine("Recent messages: {0}", inbox.Unread);
for (int i = 0; i < inbox.Count; i )
{
var message = inbox.GetMessage(i, cancel.Token);
MyAlert alert = new MyAlert(message.MessageId, message.Date.DateTime, message.Subject, message.Subject);
if (!MyAlert.alerts.Any(x => x.Id.Equals(alert.Id)))
{
MyAlert.alerts.Add(alert);\\Think of it as a method that saves the object to the database
}
CheckForUpdates(MyAlert.alerts[i]);
}
}
client.Disconnect(true);
}
}
Method checking for updates
public void CheckForUpdates(MyAlert alert)
{
double result = 0;
foreach (var item in MyAlert.alerts.Select(x => x.NameOfCostumer.Equals(alert.NameOfCostumer)))
{
if (item)
{
for (int i = 0; i < MyAlert.alerts.Count(); i )
{
result = MyAlert.alerts[i].Date.Minute - alert.Date.Minute;
Console.WriteLine("Result of:" MyAlert.alerts[i].NameOfCostumer " "
"and" " " alert.NameOfCostumer " " "is:" result);
if (result > 0 && result <= 5)
{
Console.WriteLine("You HAVE TO UPDATE this" " " MyAlert.alerts[i].NameOfAlert);
MyAlert.alerts[i].NameOfAlert = "UPDATED";
break;
}
else
{
Console.WriteLine("You DON'T have to UPDATE this:" " " MyAlert.alerts[i].NameOfAlert);
}
}
}
}
Console.WriteLine("Wave:" MyAlert.alerts.Count);
}
CodePudding user response:
This is how I figured this out with DB
public double GetInterval(DateTime a, DateTime b)
{
return a.Subtract(b).TotalMinutes;
}
public void FindUpdate(Alert newAlert, Alert matchAlert)
{
//If new Alerts arrives from same costumer with same problem till five 5 minutes
if (dAOAlert.GetAll().Any(x => x.Email.Equals(newAlert.Email) && x.Problem.NameOfAlert.Equals(newAlert.Problem.NameOfAlert))
&&
GetInterval(newAlert.Date, matchAlert.Date) > 0 && GetInterval(newAlert.Date, matchAlert.Date) <= 5)
{
//Find that Alert, and update his variables from alert, else save new alert
var item = dAOAlert.GetAll().FirstOrDefault(x => x.Email.Equals(newAlert.Email) && x.Problem.NameOfAlert.Equals(newAlert.Problem.NameOfAlert));
dAOAlert.Update(item, newAlert);
dAOAlert.Delete(newAlert);
LoadAlertGrid();
}
}
And this is how I have used this in Main method
for (int i = 0; i < inbox.Count; i )
{
var message = inbox.GetMessage(i, cancel.Token);
GetBodyText = message.TextBody;
Problem problem = new Problem(message.MessageId);
if (!dAOProblem.GetAll().Any(x => x.Message_Id.Equals(problem.Message_Id)))
{
dAOProblem.Save(problem);
Alert alert = new Alert(message.MessageId, message.Date.DateTime, message.From.ToString(), 1, problem.Id);
if (!dAOAlert.GetAll().Any(x => x.Id_MimeMessage.Equals(alert.Id_MimeMessage)))
{
dAOAlert.Save(alert);
foreach (var item in dAOAlert.GetAll())
{
FindUpdate(alert, item);
}
LoadAlertGrid();
}
else
{
MessageBox.Show("Duplicate");
}
}
}