Fix: Duplicate Device Models

Stop future duplicate device models and repair any existing duplicates
SEE:
http://discoict.com.au/forum/support/2013/2/duplicate-device-models.aspx
This commit is contained in:
Gary Sharp
2013-02-07 18:26:58 +11:00
parent d2805d8765
commit a9bbcabd87
3 changed files with 944 additions and 891 deletions
+61
View File
@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Disco.Data.Repository;
using Disco.Models.Repository;
namespace Disco.BI
{
public static class DeviceModelBI
{
// Added: 2013-02-07 G#
// Ensure Duplicate Device Models are not created by creating only one Device Model at a time
// http://www.discoict.com.au/forum/support/2013/2/duplicate-device-models.aspx
// Thanks to Michael Vorster for reporting this problem.
private static object _CreateDeviceModelLock = new object();
public static Tuple<DeviceModel, bool> GetOrCreateDeviceModel(this DbSet<DeviceModel> DeviceModelsSet, string Manufacturer, string Model, string ModelType)
{
// Already Exists?
var deviceModel = DeviceModelsSet.FirstOrDefault(dm => dm.Manufacturer == Manufacturer && dm.Model == Model);
if (deviceModel == null)
{
// Ensure only one thread/request at a time
lock (_CreateDeviceModelLock)
{
// Check again now that lock is enforced
deviceModel = DeviceModelsSet.FirstOrDefault(dm => dm.Manufacturer == Manufacturer && dm.Model == Model);
if (deviceModel == null)
{
// Create the Device Model in a different DataContext so we don't have to commit unrelated changes
using (DiscoDataContext dbContext = new DiscoDataContext())
{
var addDeviceModel = new DeviceModel
{
Manufacturer = Manufacturer,
Model = Model,
ModelType = ModelType,
Description = string.Format("{0} {1}", Manufacturer, Model)
};
dbContext.DeviceModels.Add(addDeviceModel);
dbContext.SaveChanges();
}
// Obtain the Device Model with the in-scope DataContext
// - Overhead acknowledged, but reasonable given the infrequency of occurrence
deviceModel = DeviceModelsSet.FirstOrDefault(dm => dm.Manufacturer == Manufacturer && dm.Model == Model);
return new Tuple<DeviceModel, bool>(deviceModel, true);
}
}
}
return new Tuple<DeviceModel,bool>(deviceModel, false);
}
// Added: 2013-02-07 G#
}
}
+24 -65
View File
@@ -241,23 +241,14 @@ namespace Disco.BI.DeviceBI
EnrolmentLog.LogSessionProgress(sessionId, 50, "New Device, Building Disco Instance");
EnrolmentLog.LogSessionTaskAddedDevice(sessionId, Request.DeviceSerialNumber);
DeviceProfile deviceProfile = dbContext.DeviceProfiles.Find(dbContext.DiscoConfiguration.DeviceProfiles.DefaultDeviceProfileId);
DeviceModel deviceModel = dbContext.DeviceModels.Where(dm => dm.Manufacturer == Request.DeviceManufacturer.Trim() && dm.Model == Request.DeviceModel.Trim()).FirstOrDefault();
if (deviceModel == null)
{
deviceModel = new DeviceModel
{
Manufacturer = Request.DeviceManufacturer.Trim(),
Model = Request.DeviceModel.Trim(),
ModelType = Request.DeviceModelType.Trim(),
Description = string.Format("{0} {1}", Request.DeviceManufacturer.Trim(), Request.DeviceModel)
};
dbContext.DeviceModels.Add(deviceModel);
EnrolmentLog.LogSessionTaskCreatedDeviceModel(sessionId, Request.DeviceSerialNumber, Request.DeviceManufacturer.Trim(), Request.DeviceModel.Trim());
}
var deviceModelResult = dbContext.DeviceModels.GetOrCreateDeviceModel(Request.DeviceManufacturer.Trim(), Request.DeviceModel.Trim(), Request.DeviceModel.Trim());
DeviceModel deviceModel = deviceModelResult.Item1;
if (deviceModelResult.Item2)
EnrolmentLog.LogSessionTaskCreatedDeviceModel(sessionId, Request.DeviceSerialNumber, deviceModelResult.Item1.Manufacturer, deviceModelResult.Item1.Model);
else
{
EnrolmentLog.LogSessionDevice(sessionId, Request.DeviceSerialNumber, deviceModel.Id);
}
RepoDevice = new Device
{
SerialNumber = Request.DeviceSerialNumber,
@@ -277,23 +268,13 @@ namespace Disco.BI.DeviceBI
EnrolmentLog.LogSessionTaskUpdatingDevice(sessionId, Request.DeviceSerialNumber);
if (!RepoDevice.DeviceModelId.HasValue || RepoDevice.DeviceModelId.Value == 1)
{
DeviceModel deviceModel = dbContext.DeviceModels.Where(dm => dm.Manufacturer == Request.DeviceManufacturer.Trim() && dm.Model == Request.DeviceModel.Trim()).FirstOrDefault();
if (deviceModel == null)
{
deviceModel = new DeviceModel
{
Manufacturer = Request.DeviceManufacturer.Trim(),
Model = Request.DeviceModel.Trim(),
ModelType = Request.DeviceModelType.Trim(),
Description = string.Format("{0} {1}", Request.DeviceManufacturer.Trim(), Request.DeviceModel.Trim())
};
dbContext.DeviceModels.Add(deviceModel);
EnrolmentLog.LogSessionTaskCreatedDeviceModel(sessionId, Request.DeviceSerialNumber, Request.DeviceManufacturer.Trim(), Request.DeviceModel.Trim());
}
var deviceModelResult = dbContext.DeviceModels.GetOrCreateDeviceModel(Request.DeviceManufacturer.Trim(), Request.DeviceModel.Trim(), Request.DeviceModel.Trim());
DeviceModel deviceModel = deviceModelResult.Item1;
if (deviceModelResult.Item2)
EnrolmentLog.LogSessionTaskCreatedDeviceModel(sessionId, Request.DeviceSerialNumber, deviceModelResult.Item1.Manufacturer, deviceModelResult.Item1.Model);
else
{
EnrolmentLog.LogSessionDevice(sessionId, Request.DeviceSerialNumber, deviceModel.Id);
}
RepoDevice.DeviceModel = deviceModel;
}
else
@@ -396,23 +377,15 @@ namespace Disco.BI.DeviceBI
EnrolmentLog.LogSessionProgress(sessionId, 30, "New Device, Creating Disco Instance");
EnrolmentLog.LogSessionTaskAddedDevice(sessionId, Request.DeviceSerialNumber);
DeviceProfile deviceProfile = dbContext.DeviceProfiles.Find(dbContext.DiscoConfiguration.DeviceProfiles.DefaultDeviceProfileId);
DeviceModel deviceModel = dbContext.DeviceModels.Where(dm => dm.Manufacturer == Request.DeviceManufacturer.Trim() && dm.Model == Request.DeviceModel.Trim()).FirstOrDefault();
if (deviceModel == null)
{
deviceModel = new DeviceModel
{
Manufacturer = Request.DeviceManufacturer.Trim(),
Model = Request.DeviceModel.Trim(),
ModelType = Request.DeviceModelType.Trim(),
Description = string.Format("{0} {1}", Request.DeviceManufacturer.Trim(), Request.DeviceModel.Trim())
};
dbContext.DeviceModels.Add(deviceModel);
EnrolmentLog.LogSessionTaskCreatedDeviceModel(sessionId, Request.DeviceSerialNumber, Request.DeviceManufacturer.Trim(), Request.DeviceModel.Trim());
}
var deviceModelResult = dbContext.DeviceModels.GetOrCreateDeviceModel(Request.DeviceManufacturer.Trim(), Request.DeviceModel.Trim(), Request.DeviceModel.Trim());
DeviceModel deviceModel = deviceModelResult.Item1;
if (deviceModelResult.Item2)
EnrolmentLog.LogSessionTaskCreatedDeviceModel(sessionId, Request.DeviceSerialNumber, deviceModelResult.Item1.Manufacturer, deviceModelResult.Item1.Model);
else
{
EnrolmentLog.LogSessionDevice(sessionId, Request.DeviceSerialNumber, deviceModel.Id);
}
RepoDevice = new Device
{
SerialNumber = Request.DeviceSerialNumber,
@@ -432,28 +405,14 @@ namespace Disco.BI.DeviceBI
EnrolmentLog.LogSessionProgress(sessionId, 30, "Existing Device, Updating Disco Instance");
EnrolmentLog.LogSessionTaskUpdatingDevice(sessionId, Request.DeviceSerialNumber);
DeviceModel deviceModel = dbContext.DeviceModels.Where(dm => dm.Manufacturer == Request.DeviceManufacturer.Trim() && dm.Model == Request.DeviceModel.Trim()).FirstOrDefault();
if (deviceModel == null)
{
deviceModel = new DeviceModel
{
Manufacturer = Request.DeviceManufacturer.Trim(),
Model = Request.DeviceModel.Trim(),
ModelType = Request.DeviceModelType.Trim(),
Description = string.Format("{0} {1}", Request.DeviceManufacturer.Trim(), Request.DeviceModel)
};
dbContext.DeviceModels.Add(deviceModel);
RepoDevice.DeviceModel = deviceModel;
EnrolmentLog.LogSessionTaskCreatedDeviceModel(sessionId, Request.DeviceSerialNumber, Request.DeviceManufacturer.Trim(), Request.DeviceModel.Trim());
}
var deviceModelResult = dbContext.DeviceModels.GetOrCreateDeviceModel(Request.DeviceManufacturer.Trim(), Request.DeviceModel.Trim(), Request.DeviceModel.Trim());
DeviceModel deviceModel = deviceModelResult.Item1;
if (deviceModelResult.Item2)
EnrolmentLog.LogSessionTaskCreatedDeviceModel(sessionId, Request.DeviceSerialNumber, deviceModelResult.Item1.Manufacturer, deviceModelResult.Item1.Model);
else
{
if (!RepoDevice.DeviceModelId.HasValue || RepoDevice.DeviceModelId.Value != deviceModel.Id)
{
EnrolmentLog.LogSessionDevice(sessionId, Request.DeviceSerialNumber, deviceModel.Id);
RepoDevice.DeviceModel = deviceModel;
}
EnrolmentLog.LogSessionDevice(sessionId, Request.DeviceSerialNumber, RepoDevice.DeviceModelId);
}
if (!RepoDevice.EnrolledDate.HasValue)
RepoDevice.EnrolledDate = DateTime.Now;
+33
View File
@@ -52,6 +52,9 @@ namespace Disco.Data.Repository
UpdateDeviceModelConfiguration(context);
// Removed: 2013-01-14 G#
//UpdateDeviceModelImageStorage(context);
// Added: 2013-02-07 G#
UpdateDeviceModelDuplicates(context);
}
public static void SeedDeviceProfiles(this DiscoDataContext context)
{
@@ -266,5 +269,35 @@ namespace Disco.Data.Repository
// }
//#pragma warning restore 0618
// }
// Added: 2013-02-07 G#
// Fix previous problem with duplicate device models being created if new devices enrol at the same time
// http://www.discoict.com.au/forum/support/2013/2/duplicate-device-models.aspx
// Thanks to Michael Vorster for reporting this problem.
private static void UpdateDeviceModelDuplicates(this DiscoDataContext dbContext)
{
var deviceModels = dbContext.DeviceModels.ToList();
var duplicateModels = deviceModels.GroupBy(g => string.Format("{0}|{1}", g.Manufacturer, g.Model)).Where(g => g.Count() > 1);
foreach (var duplicateModel in duplicateModels)
{
var primaryModel = duplicateModel.OrderBy(dm => dm.Id).First();
foreach (var redundantModel in duplicateModel.Where(m => m != primaryModel))
{
foreach (var affectedDevice in dbContext.Devices.Where(d => d.DeviceModelId == redundantModel.Id))
{
affectedDevice.DeviceModelId = primaryModel.Id;
}
if (!redundantModel.Description.EndsWith("** REDUNDANT **"))
{
if (redundantModel.Description.Length > 484)
redundantModel.Description = string.Format("{0} ** REDUNDANT **", redundantModel.Description.Substring(0, 484));
else
redundantModel.Description = string.Format("{0} ** REDUNDANT **", redundantModel.Description);
}
}
}
}
// End Added: 2013-02-07 G#
}
}