我知道上面的错误消息有很多问题,但似乎没有解决我的问题。我有下面的代码,它采用azure队列并从中提取事件日志条目,然后使用实体框架将它们保存在azure数据库中。大约95%的savechanges调用都会发生异常,但并不是每个人都有。当异常发生时,实体状态被添加而不被修改,并且密钥EventLogEntryID
为0,其他一些stackoverflow答案建议可能是问题。我在每次保存后处理dbcontext。非常感谢任何帮助或见解。
public static void ProcessQueueMessage([TimerTrigger("0 */5 * * * *", RunOnStartup = true)] TimerInfo timerInfo)
{
storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
// Create the queue client.
queueClient = storageAccount.CreateCloudQueueClient();
// Retrieve a reference to a container.
cloudqueue = queueClient.GetQueueReference("events");
if (!IsRunning)
{
int threads = 8;
Task[] workers = new Task[threads];
for (int i = 0; i < threads; ++i)
{
Task task = new Task(() => WorkQueue());
workers[i] = task;
task.Start();
}
try
{
Task.WaitAll(workers);
IsRunning = false;
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
if (ex.InnerException != null)
{
Console.Error.WriteLine(ex.InnerException.Message);
}
}
}
else
{
Console.Out.WriteLine("Proccess currently running");
}
}
public static void WorkQueue()
{
var error = false;
List<CloudQueueMessage> messagesList = new List<CloudQueueMessage>();
List<EventLogEntry> entriesList = new List<EventLogEntry>();
var messages = cloudqueue.GetMessages(32, TimeSpan.FromMinutes(2));
while (messages != null)
{
foreach (CloudQueueMessage cloudQueueMessage in messages)
{
messagesList.Add(cloudQueueMessage);
EventLogEntry entry = JsonConvert.DeserializeObject<EventLogEntry>(cloudQueueMessage.AsString);
if (entry != null)
{
try
{
using (var db = new EventContext())
{
db.Entries.Add(entry);
var result = db.SaveChanges() > 1;
if (result)
{
entriesList.Add(entry);
cloudqueue.DeleteMessage(cloudQueueMessage);
}
else
{
Console.Out.WriteLine("Entries not saved");
}
}
}
catch (Exception ex)
{
if (ex.InnerException != null)
{
if (ex.InnerException.InnerException != null)
{
var exception = ex.InnerException.InnerException as SqlException;
if (exception != null)
{
if (exception.Number == 2601)
{
cloudqueue.DeleteMessage(cloudQueueMessage);
}
else
{
Console.Error.WriteLine(ex.InnerException.InnerException.Message);
Console.Error.WriteLine($"Error number: {exception.Number}");
error = true;
}
}
else
{
Console.Error.WriteLine(ex.InnerException.InnerException.Message);
}
}
else
{
//Console.Error.WriteLine(ex.Message);
}
}
else
{
//Console.Error.WriteLine(ex.Message);
}
}
}
}
Console.Out.WriteLine($"{entriesList.Count} entries added");
Console.Out.WriteLine($"{messagesList.Count} messages pulled");
entriesList = new List<EventLogEntry>();
messagesList = new List<CloudQueueMessage>();
messages = !error ? cloudqueue.GetMessages(32, TimeSpan.FromMinutes(2)) : null;
}
}
public class EventLogData
{
[Key]
public int EventLogDataID { get; set; }
public string Name { get; set; }
public string Text { get; set; }
}
public class EventLogEntry
{
[Key]
public int EventLogEntryID { get; set; }
[Index("IX_CompanyID", IsClustered = false)]
[MaxLength(50)]
public string CompanyID { get; set; }
[Index("IX_EventID", IsClustered = false)]
[MaxLength(10)]
public string EventID { get; set; }
public string Version { get; set; }
public string Level { get; set; }
public string Task { get; set; }
public string Opcode { get; set; }
public string Keywords { get; set; }
[Index("IX_TimeCreatedEventRecordIDComputer", 1, IsUnique = true)]
public DateTime TimeCreated { get; set; }
[Index("IX_TimeCreatedEventRecordIDComputer", 2, IsUnique = true)]
[MaxLength(50)]
public string EventRecordID { get; set; }
public string Correlation { get; set; }
public string Channel { get; set; }
[Index("IX_TimeCreatedEventRecordIDComputer", 3, IsUnique = true)]
[MaxLength(255)]
public string Computer { get; set; }
public string Security { get; set; }
public string TargetLogonId { get; set; }
public string SubjectLogonId { get; set; }
public string HandleID { get; set; }
public string ObjectName { get; set; }
public string AccessList { get; set; }
public string ProcessName { get; set; }
public string ObjectType { get; set; }
[Index("IX_SubjectUserName", IsClustered = false)]
[MaxLength(255)]
public string SubjectUserName { get; set; }
[Index("IX_LogonType", IsClustered = false)]
[MaxLength(10)]
public string LogonType { get; set; }
[Index("IX_TargetUserName", IsClustered = false)]
[MaxLength(255)]
public string TargetUserName { get; set; }
[Index("IX_IsDelete", IsClustered = false)]
public bool IsDelete { get; set; }
public virtual ICollection<EventLogData> EventData { get; set; }
public EventLogEntry()
{
EventData = new List<EventLogData>();
}
}
class EventContext: DbContext
{
public DbSet<EventLogEntry> Entries { get; set; }
public EventContext():base("name=EventContext")
{
}
}