/// <summary> /// 指定日時より作成日が古いデータを削除する /// </summary> /// <param name="comparisonSourceDatetime">比較対象日時</param> /// <returns>削除数</returns> public int DeleteExceedsMonthsAllData(DateTime comparisonSourceDatetime) { int result = 0; try { _logger.EnterJson("{0}", new { comparisonSourceDatetime }); _dbPolly.Execute(() => { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { // 作成日時から指定月数超過しているデータを抽出し、削除する var targets = db.DtAlarm.Where(x => x.CreateDatetime < comparisonSourceDatetime); db.DtAlarm.RemoveRange(targets); result = db.SaveChanges(); } }); return(result); } catch (Exception e) { throw new RmsException("DT_ALARMテーブルのDeleteに失敗しました。", e); } finally { _logger.Leave(); } }
/// <summary> /// 引数に指定したSIDのレコードを対象にDT_ALMILOG_ANALYSIS_RESULTテーブルのIS_ALARM_JUDGEDをTRUEに更新する /// </summary> /// <param name="sidList">更新対象レコードのSID</param> /// <returns>更新レコード数</returns> public int UpdateIsAlarmJudgedTrue(IEnumerable <long> sidList) { try { _logger.EnterJson("{0}", new { sidList }); int result = 0; _dbPolly.Execute(() => { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { var targets = (from r in db.DtAlmilogAnalysisResult where sidList.Contains(r.Sid) select r).ToList(); foreach (var target in targets) { target.IsAlarmJudged = true; } result = db.SaveChanges(); } }); return(result); } catch (Exception e) { throw new RmsException("DT_ALMILOG_ANALYSIS_RESULTテーブルのUpdateに失敗しました。", e); } finally { _logger.Leave(); } }
/// <summary> /// 引数に指定したDtSoftVersionをDT_SOFT_VERSIONテーブルへ登録する /// </summary> /// <param name="inData">登録するデータ</param> /// <param name="equipmentModelCode">機器型式コード</param> /// <returns>追加したデータ。エラーが発生した場合には例外を投げるためnullを返さない</returns> public DtSoftVersion CreateDtSoftVersionIfAlreadyMessageThrowEx(DtSoftVersion inData, string equipmentModelCode) { DtSoftVersion model = null; try { _logger.EnterJson("{0}", inData); _dbPolly.Execute(() => { // メッセージIDがなければ追加 using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { // マスタテーブルから機器型式SIDを取得 var equipmentModel = db.MtEquipmentModel.FirstOrDefault(x => x.Code == equipmentModelCode); if (equipmentModel == null || equipmentModel.Sid == 0) { throw new RmsException(string.Format("機器型式コード[{0}]がマスタテーブルに存在しません。", equipmentModelCode)); } var addedAlready = db.DtSoftVersion.FirstOrDefault(x => x.MessageId == inData.MessageId); if (addedAlready != null) { throw new RmsAlreadyExistException(string.Format("MessageId [{0}] はすでに追加済みです。", inData.MessageId)); } // 機器型式SIDを設定 inData.EquipmentModelSid = equipmentModel.Sid; Rms.Server.Core.DBAccessor.Models.DtSoftVersion entity = new Rms.Server.Core.DBAccessor.Models.DtSoftVersion(inData); var dbdata = db.DtSoftVersion.Add(entity).Entity; db.SaveChanges(_timePrivder); model = dbdata.ToModel(); } }); return(model); } catch (RmsAlreadyExistException) { throw; } catch (RmsException) { throw; } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_SOFT_VERSIONテーブルへのInsertに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// 引数に指定したDtDeviceをDT_DEVICEテーブルへ登録する /// </summary> /// <param name="inData">登録するデータ</param> /// <returns>処理結果</returns> public DtDevice CreateDtDevice(DtDevice inData) { DtDevice model = null; try { _logger.EnterJson("{0}", inData); DBAccessor.Models.DtDevice entity = new DBAccessor.Models.DtDevice(inData); // 初期値GUIDはIDを割り振る if (entity.EdgeId == Guid.Empty) { entity.EdgeId = Guid.NewGuid(); } _dbPolly.Execute(() => { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { // 接続ステータスが「unconnected」のデータを取得する var unconnectedData = db.MtConnectStatus .Where(x => x.Code.Equals(Const.ConnectStatus.Unconnected)) .FirstOrDefault(); if (unconnectedData == null) { // データ設定せずに返却 return; } // 接続ステータス設定 entity.ConnectStatusSid = unconnectedData.Sid; var dbdata = db.DtDevice.Add(entity).Entity; db.SaveChanges(_timePrivder); model = dbdata.ToModel(); } }); return(model); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_DEVICEテーブルへのInsertに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// データの更新(配信ステータスを指定SIDのものにする) /// 実際の更新処理を行う /// </summary> /// <param name="sid">更新する配信グループデータのSID</param> /// <returns>更新されたDB内容</returns> private DtDeliveryGroup UpdateStatusStarted(long sid) { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { try { // 指定した配信グループSIDと一致する情報を取得する var entity = db.DtDeliveryGroup.Include(x => x.DeliveryGroupStatusS).FirstOrDefault(x => x.Sid == sid); if (entity == null) { // 値を設定せずにリターン return(null); } // 指定した配信グループが未配信状態であるかチェックする var isNotStart = entity.DeliveryGroupStatusS.Code.Equals(Utility.Const.DeliveryGroupStatus.NotStarted); if (!isNotStart) { throw new RmsCannotChangeDeliveredFileException(string.Format("配信前状態ではないDT_DELIVERY_GROUPテーブルのレコードをUpdateしようとしました。(DT_DELIVERY_GROUP.SID = {0})", sid)); } // 「開始済」の配信グループステータスSIDを取得する var startedData = db.MtDeliveryGroupStatus.Where(x => x.Code.Equals(Utility.Const.DeliveryGroupStatus.Started)).FirstOrDefault(); if (startedData == null) { // 値を設定せずにリターン return(null); } // 情報の更新 entity.DeliveryGroupStatusSid = startedData.Sid; var p = db.DtDeliveryGroup.Update(entity); db.SaveChanges(_timePrivder); return(p.Entity.ToModel()); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (DbUpdateConcurrencyException e) { // RowVersion衝突が起きた throw new RmsConflictException("DT_DELIVERY_GROUPテーブルのUpdateで競合が発生しました。", e); } catch { // SqlExceptionであれば再試行される throw; } } }
/// <summary> /// 引数に指定したDtDeviceでDT_DEVICEテーブルを更新する /// </summary> /// <param name="inData">更新するデータ</param> /// <returns>更新したデータ</returns> public DtDevice UpdateDtDevice(DtDevice inData) { DtDevice model = null; try { _logger.EnterJson("{0}", inData); DBAccessor.Models.DtDevice entity = new DBAccessor.Models.DtDevice(inData); _dbPolly.Execute(() => { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { // 指定SIDのデータがDBになければnullリターン if (db.DtDevice.AsNoTracking().FirstOrDefault(x => x.Sid == inData.Sid) == null) { return; } db.DtDevice.Attach(entity); // 全フィールドを更新する // 特定フィールドだけUpdateする場合は下記のように記述してください // db.Entry(entity).Property(x => x.UpdateDatetime).IsModified = true; db.Entry(entity).Property(x => x.InstallTypeSid).IsModified = true; db.Entry(entity).Property(x => x.EquipmentModelSid).IsModified = true; if (db.SaveChanges(_timePrivder) > 0) { // 呼び出し側に更新済みデータを返却する model = db.DtDevice.AsNoTracking().FirstOrDefault(x => x.Sid == inData.Sid)?.ToModel(); } } }); return(model); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_DEVICEテーブルのUpdateに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// データの更新(配信ステータスが「配信前」の時のみ) /// 実際の更新処理を行う /// </summary> /// <param name="inData">更新データ</param> /// <returns>更新されたDB内容</returns> private DtDeliveryGroup UpdateIfNotStart(DtDeliveryGroup inData) { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { try { // 指定した配信グループSIDと一致する情報を取得する var entity = db.DtDeliveryGroup .Include(x => x.DeliveryGroupStatusS) .FirstOrDefault(x => x.Sid == inData.Sid); if (entity == null) { return(null); } // 指定した配信ステータスSIDを検索し、未配信状態であるかチェックする var isNotStart = entity.DeliveryGroupStatusS.Code.Equals(Utility.Const.DeliveryGroupStatus.NotStarted); if (!isNotStart) { throw new RmsCannotChangeDeliveredFileException(string.Format("配信前状態ではないDT_DELIVERY_GROUPテーブルのレコードをUpdateしようとしました。(DT_DELIVERY_GROUP.SID = {0})", inData.Sid)); } // 情報の更新 entity.Name = inData.Name; entity.StartDatetime = inData.StartDatetime; entity.DownloadDelayTime = inData.DownloadDelayTime; // コンテキスト管理のRowVersionを投入値に置き換えて、DBデータと比較させる(Attatch処理以外では必要) db.Entry(entity).Property(e => e.RowVersion).OriginalValue = inData.RowVersion; var p = db.DtDeliveryGroup.Update(entity); db.SaveChanges(_timePrivder); return(p.Entity.ToModel()); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (DbUpdateConcurrencyException e) { // RowVersion衝突が起きた throw new RmsConflictException("DT_DELIVERY_GROUPテーブルのUpdateで競合が発生しました。", e); } catch { // SqlExceptionであれば再試行される throw; } } }
/// <summary> /// デバイスツイン更新イベントを受信して端末テーブルの「リモート接続UID」と「RMSソフトバージョン」を更新する /// </summary> /// <param name="sid">端末SID</param> /// <param name="data">更新データ</param> /// <returns>更新したデータ。テーブルが更新されなかった場合にはnullを返す</returns> public DtDevice UpdateDeviceInfoByTwinChanged(long sid, DtTwinChanged data) { DtDevice model = null; try { _logger.EnterJson("{0}", sid); _dbPolly.Execute(() => { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { string remoteConnectionUid = data.RemoteConnectionUid; string rmsSoftVersion = data.SoftVersion; // リモート接続UIDとRMSソフトバージョンを更新する DtDevice inData = new DtDevice() { Sid = sid, RemoteConnectUid = remoteConnectionUid, RmsSoftVersion = rmsSoftVersion }; DBAccessor.Models.DtDevice entity = new DBAccessor.Models.DtDevice(inData); db.DtDevice.Attach(entity); // リモート接続UIDとRMSソフトバージョンを更新する db.Entry(entity).Property(x => x.RemoteConnectUid).IsModified = true; db.Entry(entity).Property(x => x.RmsSoftVersion).IsModified = true; if (db.SaveChanges(_timePrivder) > 0) { model = entity.ToModel(); } } }); return(model); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_DEVICEテーブルのUpdateに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// 引数に指定したDtSmartAnalysisResultでDT_SMART_ANALYSIS_RESULTテーブルを更新する /// </summary> /// <param name="inData">更新するデータ</param> /// <returns>更新したデータ</returns> public DtSmartAnalysisResult UpdateDtSmartAnalysisResult(DtSmartAnalysisResult inData) { DtSmartAnalysisResult model = null; try { _logger.EnterJson("{0}", inData); DBAccessor.Models.DtSmartAnalysisResult entity = new DBAccessor.Models.DtSmartAnalysisResult(inData); // バリデーション Validator.ValidateObject(entity, new ValidationContext(entity, null, null)); _dbPolly.Execute(() => { entity.UpdateDatetime = _timePrivder.UtcNow; using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { db.DtSmartAnalysisResult.Attach(entity); // 全フィールドを更新する // 特定フィールドだけUpdateする場合は下記のように記述してください // db.Entry(entity).Property(x => x.UpdateDatetime).IsModified = true; db.Entry(entity).State = Microsoft.EntityFrameworkCore.EntityState.Modified; if (db.SaveChanges() > 0) { model = entity.ToModel(); } } }); return(model); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_SMART_ANALYSIS_RESULTテーブルのUpdateに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// 引数に指定したDtInventoryをDT_INVENTORYテーブルへ登録する /// </summary> /// <param name="inData">登録するデータ</param> /// <returns>追加したデータ。エラーが発生した場合には例外を投げるためnullを返さない</returns> public DtInventory CreateDtInventoryIfAlreadyMessageThrowEx(DtInventory inData) { DtInventory model = null; try { _logger.EnterJson("{0}", inData); DBAccessor.Models.DtInventory entity = new DBAccessor.Models.DtInventory(inData); _dbPolly.Execute(() => { // メッセージIDがなければ追加 using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { var addedAlready = db.DtInventory.FirstOrDefault(x => x.MessageId == inData.MessageId); if (addedAlready != null) { throw new RmsAlreadyExistException(string.Format("MessageId [{0}] はすでに追加済みです。", inData.MessageId)); } var dbdata = db.DtInventory.Add(entity).Entity; db.SaveChanges(_timePrivder); model = dbdata.ToModel(); } }); return(model); } catch (RmsAlreadyExistException) { throw; } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_INVENTORYテーブルへのInsertに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// 引数に指定したDtDeliveryFileをDT_DELIVERY_FILEテーブルへ登録する /// </summary> /// <param name="inData">登録するデータ</param> /// <returns>処理結果</returns> public DtDeliveryFile CreateDtDeliveryFile(DtDeliveryFile inData) { DtDeliveryFile model = null; try { _logger.EnterJson("{0}", inData); DBAccessor.Models.DtDeliveryFile entity = new DBAccessor.Models.DtDeliveryFile(inData); _dbPolly.Execute(() => { DateTime createdAt = _timePrivder.UtcNow; entity.CreateDatetime = createdAt; entity.UpdateDatetime = createdAt; foreach (DBAccessor.Models.DtDeliveryModel child in entity.DtDeliveryModel) { child.CreateDatetime = createdAt; } using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { var dbdata = db.DtDeliveryFile.Add(entity).Entity; db.SaveChanges(); model = dbdata.ToModel(); } }); return(model); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_DELIVERY_FILEテーブルへのInsertに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// 指定日時より作成日が古い非最新データを削除する /// </summary> /// <param name="comparisonSourceDatetime">比較対象日時</param> /// <returns>削除数</returns> public int DeleteExceedsMonthsAllData(DateTime comparisonSourceDatetime) { int result = 0; try { _logger.Enter($"{nameof(comparisonSourceDatetime)}={comparisonSourceDatetime}"); _dbPolly.Execute(() => { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { var CollectDatetime = new SqlParameter("CollectDatetime", comparisonSourceDatetime); // 収集日時から指定月数超過しているデータを抽出し、削除する var targets = db.DtSoftVersion .FromSql( @" Select * From core.DT_SOFT_VERSION tbl1 Where tbl1.COLLECT_DATETIME < @CollectDatetime and tbl1.COLLECT_DATETIME <> (SELECT MAX(tbl2.COLLECT_DATETIME) FROM core.DT_SOFT_VERSION tbl2 Where tbl1.DEVICE_SID = tbl2.DEVICE_SID)", CollectDatetime); db.DtSoftVersion.RemoveRange(targets); result = db.SaveChanges(); } }); return(result); } catch (Exception e) { throw new RmsException("DT_SOFT_VERSIONテーブルのDeleteに失敗しました。", e); } finally { _logger.Leave($"{nameof(result)}={result}"); } }
/// <summary> /// 引数に指定したDtDeliveryGroupをDT_DELIVERY_GROUPテーブルへ登録する /// </summary> /// <param name="inData">登録するデータ</param> /// <returns>処理結果</returns> public DtDeliveryGroup CreateDtDeliveryGroup(DtDeliveryGroup inData) { DtDeliveryGroup model = null; try { _logger.EnterJson("{0}", inData); DBAccessor.Models.DtDeliveryGroup entity = new DBAccessor.Models.DtDeliveryGroup(inData); _dbPolly.Execute(() => { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { var statusNotStart = db.MtDeliveryGroupStatus.FirstOrDefault(x => x.Code.Equals(Const.DeliveryGroupStatus.NotStarted)); if (statusNotStart == null) { return; } entity.DeliveryGroupStatusSid = statusNotStart.Sid; var dbdata = db.DtDeliveryGroup.Add(entity).Entity; db.SaveChanges(_timePrivder); model = dbdata.ToModel(); } }); return(model); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_DELIVERY_GROUPテーブルへのInsertに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// 引数に指定したDtSmartAnalysisResultをDT_SMART_ANALYSIS_RESULTテーブルへ登録する /// </summary> /// <param name="inData">登録するデータ</param> /// <returns>処理結果</returns> public DtSmartAnalysisResult CreateDtSmartAnalysisResult(DtSmartAnalysisResult inData) { DtSmartAnalysisResult model = null; try { _logger.EnterJson("{0}", inData); DBAccessor.Models.DtSmartAnalysisResult entity = new DBAccessor.Models.DtSmartAnalysisResult(inData); // バリデーション Validator.ValidateObject(entity, new ValidationContext(entity, null, null)); _dbPolly.Execute(() => { entity.CreateDatetime = _timePrivder.UtcNow; entity.UpdateDatetime = _timePrivder.UtcNow; using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { var dbdata = db.DtSmartAnalysisResult.Add(entity).Entity; db.SaveChanges(); model = dbdata.ToModel(); } }); return(model); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_SMART_ANALYSIS_RESULTテーブルへのInsertに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// 引数に指定したDtAlarmをDT_ALARMテーブルへ登録する /// </summary> /// <param name="inData">登録するデータ</param> /// <returns>処理結果</returns> public DtAlarm CreateDtAlarm(DtAlarm inData) { DtAlarm model = null; try { _logger.EnterJson("{0}", inData); DBAccessor.Models.DtAlarm entity = new DBAccessor.Models.DtAlarm(); entity.CopyExcludingEquipmentFrom(inData); // バリデーション Validator.ValidateObject(entity, new ValidationContext(entity, null, null)); _dbPolly.Execute(() => { entity.CreateDatetime = _timeProvider.UtcNow; using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { var dbdata = db.DtAlarm.Add(entity).Entity; db.SaveChanges(); model = dbdata.ToModelExcludedDtEquipment(); } }); return(model); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_ALARMテーブルへのInsertに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// DT_DEVICE_FILEテーブルからDtDeviceFileを削除する /// </summary> /// <param name="sid">削除するデータのSID</param> /// <returns>削除したデータ</returns> public DtDeviceFile DeleteDtDeviceFile(long sid) { DtDeviceFile model = null; try { _logger.Enter($"{nameof(sid)}={sid}"); DBAccessor.Models.DtDeviceFile entity = new DBAccessor.Models.DtDeviceFile() { Sid = sid }; _dbPolly.Execute(() => { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { db.DtDeviceFile.Attach(entity); db.DtDeviceFile.Remove(entity); if (db.SaveChanges() > 0) { model = entity.ToModel(); } } }); return(model); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_DEVICE_FILEテーブルのDeleteに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// DT_DEVICEテーブルからDtDeviceを削除する /// </summary> /// <param name="sid">削除するデータのSID</param> /// <param name="equipmentUid">削除するデータのデバイスUID</param> /// <param name="remoteConnectUid">削除するデータのリモート接続UID</param> /// <returns>削除したデータ</returns> public DtDevice DeleteDtDevice(long sid, string equipmentUid, string remoteConnectUid) { DtDevice model = null; try { _logger.Enter($"{nameof(sid)}={sid} {nameof(equipmentUid)}={equipmentUid} {nameof(remoteConnectUid)}={remoteConnectUid}"); DBAccessor.Models.DtDevice entity = new DBAccessor.Models.DtDevice() { Sid = sid, EquipmentUid = equipmentUid, RemoteConnectUid = remoteConnectUid }; _dbPolly.Execute(() => { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { db.DtDevice.Attach(entity); db.DtDevice.Remove(entity); if (db.SaveChanges(_timePrivder) > 0) { model = entity.ToModel(); } } }); return(model); } catch (Exception e) { throw new RmsException("DT_DEVICEテーブルのDeleteに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// 引数に指定したMtInstallResultStatusをMT_INSTALL_RESULT_STATUSテーブルへ登録する /// </summary> /// <param name="inData">登録するデータ</param> /// <returns>処理結果</returns> public MtInstallResultStatus CreateMtInstallResultStatus(MtInstallResultStatus inData) { MtInstallResultStatus model = null; try { _logger.EnterJson("{0}", inData); DBAccessor.Models.MtInstallResultStatus entity = new DBAccessor.Models.MtInstallResultStatus(inData); _dbPolly.Execute(() => { entity.CreateDatetime = _timePrivder.UtcNow; using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { var dbdata = db.MtInstallResultStatus.Add(entity).Entity; db.SaveChanges(); model = dbdata.ToModel(); } }); return(model); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("MT_INSTALL_RESULT_STATUSテーブルへのInsertに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// DT_PARENT_CHILD_CONNECTテーブルにメッセージを追加またはメッセージの内容で更新処理を行う(親フラグ=trueの場合) /// </summary> /// <param name="inData">更新データ</param> /// <returns>追加または更新したデータ。「確認日時」が既存レコードより古く更新しなかった場合には、nullを返す</returns> public DtParentChildConnect Save(DtParentChildConnectFromParent inData) { DtParentChildConnect model = null; try { _dbPolly.Execute(() => { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) using (var tran = db.Database.BeginTransaction()) { // 現在時刻を取得 var now = _timePrivder.Now; // メッセージクラス→Modelクラス変換時に、通信が成功だった場合は最終接続日時にデータが格納される // ここで初期値だった場合には通信失敗と判断できる if (inData.ParentLastConnectDatetime == null || inData.ParentLastConnectDatetime == default(DateTime)) { inData.ParentLastConnectDatetime = now; } // DB格納データクラス DBAccessor.Models.DtParentChildConnect entity = CreateEntityFromParent(inData, db); // 親機器 - 子機器 - 親機器確認結果の組み合わせをチェックする // 3つの組み合わせでレコードを一意に決めることができる var sids = CreateSqlParameterSet(entity.ParentDeviceSid, entity.ChildDeviceSid); DBAccessor.Models.DtParentChildConnect targetRecord = db.DtParentChildConnect.FromSql(SelectParentSqlCommand, sids).AsNoTracking().FirstOrDefault(); if (targetRecord == null || targetRecord.Sid == 0) { // 作成日時+更新日時 // 通常はSaveChangesにTimeProvideを渡し、DBが自動的に作成日時と更新日時を設定する。 // しかし親子間通信データについては、 // 通信失敗のケースにおいて最終更新日時にはレコード作成日時を格納する // (nullを回避しつつ、通信失敗ケースであったことを後から判断できるようにするため)。 // DBが自動的に時刻を設定した場合に、リポジトリ内で取得した時刻と時間差が発生する可能性があるため、 // リポジトリ内で明示的に時刻を取得してDBにレコードを挿入する。 entity.CreateDatetime = now; entity.UpdateDatetime = now; // レコード追加 var dbdata = db.DtParentChildConnect.Add(entity).Entity; // 最終日時更新データと作成日時・更新日時を一致させたいので、TimeProviderは渡さずに明示的な日時データを使う db.SaveChanges(); model = dbdata.ToModel(); } else { // データの時刻チェック: データがDBに格納されたデータよりも新しい場合のみ更新処理を行う // DBよりも古い確認時刻だった場合には更新せずにnullを返す DateTime?dbTime = targetRecord.ParentConfirmDatetime; if (dbTime == null || inData.ParentConfirmDatetime.Value.CompareTo(dbTime.Value) > 0) { // 更新対象のレコードのSIDを設定 entity.Sid = targetRecord.Sid; db.DtParentChildConnect.Attach(entity); // 更新のあったデータのみを更新する db.Entry(entity).Property(x => x.ParentConfirmDatetime).IsModified = true; db.Entry(entity).Property(x => x.ParentResult).IsModified = true; if (entity.ParentResult != null && entity.ParentResult.Value) { db.Entry(entity).Property(x => x.ParentLastConnectDatetime).IsModified = true; } db.SaveChanges(_timePrivder); model = entity.ToModel(); } } // トランザクション終了 tran.Commit(); } }); return(model); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_PARENT_CHILD_CONNECTテーブルの更新処理に失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// 引数に指定したDtPlusServiceBillLogをDT_PLUS_SERVICE_BILL_LOGテーブルへ登録する /// </summary> /// <param name="inData">登録するデータ</param> /// <returns>追加したデータ。エラーが発生した場合には例外を投げるためnullを返さない</returns> public DtPlusServiceBillLog Upsert(DtPlusServiceBillLog inData) { DtPlusServiceBillLog model = null; try { _logger.EnterJson("{0}", inData); DBAccessor.Models.DtPlusServiceBillLog entity = new DBAccessor.Models.DtPlusServiceBillLog(inData); _dbPolly.Execute(() => { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { // 重複チェック var existing = db.DtPlusServiceBillLog .FirstOrDefault(x => x.StudyInstanceUid == inData.StudyInstanceUid && x.TypeName == inData.TypeName); if (existing == null) { // 追加 db.DtPlusServiceBillLog.Add(entity); } else { // 計測日時が古いデータで更新しないようにする。 // 呼び出し側のパラメタチェックでかかるはずだが、 // 日時がnullableなので念のため既存日時がnullの場合は更新するようにしておく。 if (existing.MeasureDatetime < inData.MeasureDatetime || existing.MeasureDatetime == null) { // 更新処理 entity.Sid = existing.Sid; db.DtPlusServiceBillLog.Attach(entity); db.Entry(entity).Property(x => x.DeviceSid).IsModified = true; db.Entry(entity).Property(x => x.SourceEquipmentUid).IsModified = true; //// db.Entry(entity).Property(x => x.TypeName).IsModified = true; db.Entry(entity).Property(x => x.BillFlg).IsModified = true; db.Entry(entity).Property(x => x.PatientId).IsModified = true; db.Entry(entity).Property(x => x.Sex).IsModified = true; db.Entry(entity).Property(x => x.Age).IsModified = true; //// db.Entry(entity).Property(x => x.StudyInstanceUid).IsModified = true; db.Entry(entity).Property(x => x.SopInstanceUid).IsModified = true; db.Entry(entity).Property(x => x.StudyDatetime).IsModified = true; db.Entry(entity).Property(x => x.MeasureDatetime).IsModified = true; db.Entry(entity).Property(x => x.CollectDatetime).IsModified = true; db.Entry(entity).Property(x => x.UpdateDatetime).IsModified = true; } else { // 古いデータでの更新を弾く、AlreadyExistとはニアリーイコールではあるが、丸める new RmsAlreadyExistException(string.Format("StudyInstanceUid [{0}], TypeName[{1}] はすでに追加済みです。", inData.StudyInstanceUid, inData.TypeName)); } } if (db.SaveChanges(_timePrivder) > 0) { // 呼び出し側に更新済みデータを返却する model = db.DtPlusServiceBillLog.FirstOrDefault(x => x.Sid == inData.Sid)?.ToModel(); } } }); return(model); } catch (RmsAlreadyExistException) { throw; } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_PLUS_SERVICE_BILL_LOGテーブルへのInsertに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// 端末テーブルの接続ステータスを更新する /// </summary> /// <param name="sid">端末SID</param> /// <param name="connectionEventTimeInfo">接続/切断イベント時刻情報</param> /// <returns>更新したデータ。ステータスに変更がなかった場合にはnullを返す</returns> public DtDevice UpdateDeviceConnectionStatus(long sid, ConnectionEventTimeInfo connectionEventTimeInfo) { DtDevice model = null; try { _logger.EnterJson("{0}", sid); _dbPolly.Execute(() => { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { // 該当するステータスSIDをマスタテーブルから取得する var record = db.MtConnectStatus.FirstOrDefault(x => x.Code == connectionEventTimeInfo.Status); if (record == null || record.Sid == 0) { throw new RmsException("接続ステータスマスターテーブルに該当するステータスが存在しませんでした。"); } // ステータスSID, 接続開始日時, 接続更新日時 DtDevice inData = new DtDevice() { Sid = sid, ConnectStatusSid = record.Sid, ConnectStartDatetime = connectionEventTimeInfo.EventTime, ConnectUpdateDatetime = connectionEventTimeInfo.EventTime }; DBAccessor.Models.DtDevice entity = new DBAccessor.Models.DtDevice(inData); db.DtDevice.Attach(entity); // 接続ステータスが更新されるのでステータスSIDと接続更新日時は更新対象 db.Entry(entity).Property(x => x.ConnectStatusSid).IsModified = true; db.Entry(entity).Property(x => x.ConnectUpdateDatetime).IsModified = true; // 初回接続フラグがtrueのときは接続開始日時も更新対象 if (connectionEventTimeInfo.IsFirstConnection) { db.Entry(entity).Property(x => x.ConnectStartDatetime).IsModified = true; } if (db.SaveChanges(_timePrivder) > 0) { model = entity.ToModel(); } } }); return(model); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_DEVICEテーブルのUpdateに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// 引数指定グループ内の配信結果内で、ゲートウェイ機器SIDをもつデータの適用結果ステータスをmessagesentにして作成する /// </summary> /// <remarks>配信グループデータは参照のみ行い、メンバを変更しない</remarks> /// <param name="inData">配信グループデータ</param> /// <param name="gatewaySid">ゲートウェイ機器SID</param> /// <returns>追加した適用結果データ群</returns> public IEnumerable <DtInstallResult> CreateDtInstallResultStatusSent(DtDeliveryGroup inData, long gatewaySid) { Assert.IfNull(inData); Assert.IfNull(inData.DtDeliveryResult); IEnumerable <DtInstallResult> models = new List <DtInstallResult>(); try { _logger.EnterJson("{0}", inData); // 現在時刻はここで記録 DateTime nowTime = _timePrivder.UtcNow; // 指定したゲートウェイ機器SIDをもつ配信結果を抽出する var results = inData.DtDeliveryResult.Where(x => x.GwDeviceSid == gatewaySid); if (!results.Any()) { // 空データを返却 return(models); } _dbPolly.Execute(() => { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { List <DBAccessor.Models.DtInstallResult> dbModels = new List <DBAccessor.Models.DtInstallResult>(); // 「送信済」の適用結果ステータスSIDを取得する var sentData = db.MtInstallResultStatus.Where(x => x.Code.Equals(InstallResultStatus.MessageSent)).FirstOrDefault(); if (sentData == null) { // 値を設定せずに返却 return; } // 各配信結果SID・端末SIDをもつ適用結果データを作成する foreach (var result in results) { var installResult = new DBAccessor.Models.DtInstallResult() { DeviceSid = result.DeviceSid, DeliveryResultSid = result.Sid, InstallResultStatusSid = sentData.Sid, CollectDatetime = nowTime }; var dbData = db.DtInstallResult.Add(installResult).Entity; dbModels.Add(dbData); } db.SaveChanges(_timePrivder); models = dbModels.Select(x => x.ToModel()); } }); return(models); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_INSTALL_RESULTテーブルへのInsertに失敗しました。", e); } finally { _logger.LeaveJson("{0}", models); } }
/// <summary> /// 配信結果ステータスを更新する /// </summary> /// <param name="gatewaySid">最上位(ゲートウェイ)機器SID</param> /// <param name="statusCode">ステータス</param> /// <returns>結果</returns> /// <remarks>ステータスはUtility.Consts.InstallResultStatusに定義されている</remarks> private DtInstallResult UpdateInstallResultStatus(long gatewaySid, string statusCode) { DtInstallResult model = null; try { _logger.EnterJson("{0}", new { gatewaySid, statusCode }); _dbPolly.Execute(() => { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { DBAccessor.Models.DtInstallResult entity = null; // 更新対象レコードを取得する entity = db.DtInstallResult.Where(x => /*x.IsLatest &&*/ x.DeliveryResultS.GwDeviceSid == gatewaySid).FirstOrDefault(); if (entity == null || entity.Sid == 0) { // 対象レコードなしエラー throw new RmsException("更新対象となる適用結果データレコードが見つかりませんでした。"); } // 「送信済」の適用結果ステータスSIDを取得する var status = db.MtInstallResultStatus.Where(x => x.Code.Equals(statusCode)).FirstOrDefault(); if (status == null || status.Sid == 0) { // 対象レコードなしエラー throw new RmsException("指定したステータスコードが.MT_INSTALL_RESULT_STATUSテーブルに存在しませんでした。"); } // ステータスSIDを更新 entity.InstallResultStatusSid = status.Sid; // DB更新処理 db.DtInstallResult.Attach(entity); db.Entry(entity).Property(x => x.InstallResultStatusSid).IsModified = true; if (db.SaveChanges() > 0) { model = entity.ToModel(); } db.SaveChanges(_timePrivder); model = entity.ToModel(); } }); return(model); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_INSTALL_RESULTテーブルへのInsertに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// 引数に指定したDtDeviceFileをDT_DEVICE_FILEテーブルへ登録する /// 既にレコードが存在する場合は登録ではなく当該レコードの更新処理を行う /// また当該レコードに紐づいたDT_DEVICE_FILE_ATTRIBUTEテーブルの更新を行う /// </summary> /// <param name="inData">登録するデータ</param> /// <returns>処理結果</returns> public DtDeviceFile CreateOrUpdateDtDeviceFile(DtDeviceFile inData) { DtDeviceFile model = null; // 更新日時 // DtDeviceFileAttribute更新時に明示的に日時データを渡す必要があるため、 // レコード作成および更新日時はすべて明示的に設定する var now = _timePrivder.UtcNow; try { _logger.EnterJson("{0}", inData); _dbPolly.Execute(() => { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) using (var tran = db.Database.BeginTransaction()) { string container = inData.Container; string filePath = inData.FilePath; var deviceFileModel = db.DtDeviceFile.FirstOrDefault( x => x.Container.Equals(container, StringComparison.OrdinalIgnoreCase) && x.FilePath.Equals(filePath, StringComparison.OrdinalIgnoreCase)); DBAccessor.Models.DtDeviceFile entity; if (deviceFileModel == null || deviceFileModel.Sid == 0) { inData.CreateDatetime = now; inData.UpdateDatetime = now; entity = new DBAccessor.Models.DtDeviceFile(inData); // コンテナ名とファイルパスをキーにして見つからなければレコード追加 entity = db.DtDeviceFile.Add(entity).Entity; } else { // 端末ファイル更新 deviceFileModel.SourceEquipmentUid = inData.SourceEquipmentUid; deviceFileModel.CollectDatetime = inData.CollectDatetime; deviceFileModel.UpdateDatetime = now; entity = deviceFileModel; // コンテナ名とファイルパスをキーにしてレコードが見つかった場合は、 // 端末ファイルデータおよび紐づく端末ファイル属性レコードの更新を行う // 端末ファイル属性については、以下の処理を行う // ・同じNameを持つレコードが存在しない場合はレコード追加 // ・同じNameを持つレコードが存在する場合はレコードを更新 // ・既に存在するレコードのNameが追加するレコードの中に存在しない場合は、当該レコードを削除 // 端末ファイル属性 var inDeviceFileAttributeModel = inData.DtDeviceFileAttribute; var actualDeviceFileAttributeModel = db.DtDeviceFileAttribute.Where(x => x.DeviceFileSid == deviceFileModel.Sid); // 端末ファイル属性テーブルに存在するが、追加するレコードの中に存在しないものは削除する foreach (var attr in actualDeviceFileAttributeModel) { var inAttrData = inDeviceFileAttributeModel.FirstOrDefault(x => x.Name.Equals(attr.Name, StringComparison.OrdinalIgnoreCase)); if (inAttrData == null) { db.DtDeviceFileAttribute.Remove(attr); } } // 端末ファイル属性テーブルに存在しないものは追加、存在するものは更新 foreach (var attr in inDeviceFileAttributeModel) { var found = actualDeviceFileAttributeModel.FirstOrDefault(x => x.Name.Equals(attr.Name, StringComparison.OrdinalIgnoreCase)); DBAccessor.Models.DtDeviceFileAttribute deviceFileAttributeEntity; if (found == null || found.Sid == 0) { attr.DeviceFileSid = deviceFileModel.Sid; attr.CreateDatetime = now; attr.UpdateDatetime = now; deviceFileAttributeEntity = new DBAccessor.Models.DtDeviceFileAttribute(attr); // レコード追加 _ = db.DtDeviceFileAttribute.Add(deviceFileAttributeEntity).Entity; } else { // レコード更新 found.Value = attr.Value; found.UpdateDatetime = now; } } } db.SaveChanges(); model = entity.ToModel(); // トランザクション終了 tran.Commit(); } }); return(model); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_DEVICE_FILEテーブルへのInsertに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// 引数に指定したDtInstallResultをDT_INSTALL_RESULTテーブルへ登録する /// </summary> /// <param name="inData">登録するデータ</param> /// <param name="state">状態。適用結果ステータスマスタテーブルのコード値が入る。</param> /// <returns>追加したデータ。配信グループデータテーブルの更新に失敗した場合はnullを返す。</returns> /// <remarks> /// すべての処理に成功した場合には適用結果データテーブルに登録したデータを返す。 /// 配信グループデータテーブルの更新に失敗した場合はnullを返す。 /// 適用結果データテーブルへの登録に失敗した場合には、例外を投げる。 /// </remarks> public DtInstallResult CreateDtInstallResultIfAlreadyMessageThrowEx(DtInstallResult inData, string state) { DtInstallResult model = null; try { _logger.EnterJson("{0}", inData); // グループステータス更新失敗フラグ bool failedToUpdateGroupStatus = false; DBAccessor.Models.DtDeliveryGroup deliveryGroupEntity = new DBAccessor.Models.DtDeliveryGroup { DeliveryGroupStatusSid = 0 }; _dbPolly.Execute(() => { // メッセージIDがなければ追加 using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { // マスタテーブルから適用結果ステータスSIDを取得 var installResultStatus = db.MtInstallResultStatus.FirstOrDefault(x => x.Code == state); if (installResultStatus == null || installResultStatus.Sid == 0) { throw new RmsException(string.Format("状態[{0}]がマスタテーブルに存在しません。", state)); } var addedAlready = db.DtInstallResult.FirstOrDefault(x => x.MessageId == inData.MessageId); if (addedAlready != null) { throw new RmsAlreadyExistException(string.Format("MessageId [{0}] はすでに追加済みです。", inData.MessageId)); } // 適用結果データテーブルの更新処理 DBAccessor.Models.DtInstallResult dbdata; { // 適用結果ステータスSIDを設定 inData.InstallResultStatusSid = installResultStatus.Sid; DBAccessor.Models.DtInstallResult entity = new DBAccessor.Models.DtInstallResult(inData); // メッセージを適用結果データテーブルに保存 // 適用結果データテーブルの更新は、配信グループデータテーブル更新の成功/失敗に依存しない仕様のため、先にDB保存処理を呼ぶ dbdata = db.DtInstallResult.Add(entity).Entity; db.SaveChanges(_timePrivder); } // 配信グループデータテーブルの更新処理 { // 適用結果ステータスマスタテーブルから"completed"に該当するSIDを取得する long completedStatusSid = db.MtDeliveryGroupStatus.FirstOrDefault(x => x.Code == Const.DeliveryGroupStatus.Completed).Sid; // 更新された配信グループデータテーブルのレコード数 int affectedRows = 0; // 適用結果データテーブルの配信結果SIDから配信結果データテーブルのレコードを抽出 var deliveryResult = db.DtDeliveryResult.FirstOrDefault(x => x.Sid == inData.DeliveryResultSid); if (deliveryResult != null) { // メッセージが所属する配信グループのSID long targetDeliveryGroupSid = deliveryResult.DeliveryGroupSid; // SQL文を発行する var sqlParamForSid = new SqlParameter(SqlKeyForSid, targetDeliveryGroupSid); var sqlParamForGroupStatusSid = new SqlParameter(SqlKeyForGroupStatusSid, completedStatusSid); var sqlParams = new[] { sqlParamForGroupStatusSid, sqlParamForSid }; try { affectedRows = db.Database.ExecuteSqlCommand(SqlCommandToUpdateDeliveryGroupStatus, sqlParams); if (affectedRows <= 0) { _logger.Debug(string.Format("メッセージ[{0}]が所属する配信グループIDのステータスに変更はありませんでした。", inData.MessageId)); } } catch (Exception) { // 配信グループデータ更新失敗フラグを立てる failedToUpdateGroupStatus = true; _logger.Debug(string.Format("メッセージ[{0}]が所属する配信グループIDのステータス更新に失敗しました。", inData.MessageId)); } } else { // 配信結果はメッセージの定義上null許可のため、配信結果が存在しないケースがある _logger.Debug(string.Format("メッセージ[{0}]が所属する配信グループIDがnullであるため配信グループデータテーブルは更新しませんでした。", inData.MessageId)); } db.SaveChanges(_timePrivder); } model = dbdata.ToModel(); } }); if (failedToUpdateGroupStatus) { // 配信グループデータ更新失敗時にはnullを返す return(null); } return(model); } catch (RmsAlreadyExistException) { // メッセージ追加済みエラー throw; } catch (RmsException) { throw; } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (Exception e) { throw new RmsException("DT_INSTALL_RESULTテーブルへのInsertまたはDT_DELIVERY_GROUPのUpdateに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }
/// <summary> /// データの更新(配信ステータスが「配信前」の時のみ) /// 実際の更新処理を行う /// </summary> /// <param name="inData">更新データ</param> /// <param name="isSame">更新要否の判定メソッド</param> /// <param name="updater">更新メソッド</param> /// <param name="option">更新処理オプション</param> /// <returns>更新されたDB内容</returns> private DtDeliveryFile Update( DtDeliveryFile inData, Func <DBAccessor.Models.DtDeliveryFile, DtDeliveryFile, bool> isSame, Func <DBAccessor.Models.RmsDbContext, DBAccessor.Models.DtDeliveryFile, DtDeliveryFile, DBAccessor.Models.DtDeliveryFile> updater, UpdateOption option) { // 複数回のSQL実行を競合なく実行・ロールバックさせるためにトランザクションを用いる using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) using (var tran = db.Database.BeginTransaction()) { try { var entity = db.DtDeliveryFile .Include(x => x.DtDeliveryModel) .FirstOrDefault(x => x.Sid == inData.Sid); if (entity == null) { return(null); } // isSame()の結果同一と判定されたら更新不要のため処理終了 if (isSame(entity, inData)) { return(entity.ToModel()); } if (option == UpdateOption.OnlyNotStart) { // 指定した配信ファイルSIDを持つ配信グループを検索し、そのすべての配信ステータスが未配信状態であるかチェックする var isAllNotStarted = db.DtDeliveryGroup .Where(x => x.DeliveryFileSid == inData.Sid) .Include(x => x.DeliveryGroupStatusS) .All(x => x.DeliveryGroupStatusS.Code.Equals(Utility.Const.DeliveryGroupStatus.NotStarted)); if (!isAllNotStarted) { throw new RmsCannotChangeDeliveredFileException(string.Format("配信前状態ではないDT_DELIVERY_FILEテーブルのレコードをUpdateしようとしました。(DT_DELIVERY_FILE.SID = {0})", inData.Sid)); } } // 情報の更新 entity = updater(db, entity, inData); // コンテキスト管理のRowVersionを投入値に置き換えて、DBデータと比較させる(Attatch処理以外では必要) db.Entry(entity).Property(e => e.RowVersion).OriginalValue = inData.RowVersion; var p = db.DtDeliveryFile.Update(entity); db.SaveChanges(); // トランザクション終了 tran.Commit(); return(p.Entity.ToModel()); } catch (ValidationException e) { throw new RmsParameterException(e.ValidationResult.ErrorMessage, e); } catch (DbUpdateConcurrencyException e) { // RowVersion衝突が起きた tran.Rollback(); throw new RmsConflictException("DT_DELIVERY_FILEテーブルのUpdateで競合が発生しました。", e); } catch { // SqlExceptionであれば再試行される tran.Rollback(); throw; } } }
/// <summary> /// データの削除 /// </summary> /// <param name="sid">削除するデータのSID</param> /// <param name="rowVersion">rowversion</param> /// <returns>削除したデータ</returns> public DtDeliveryGroup DeleteDtDeliveryGroup(long sid, byte[] rowVersion) { DtDeliveryGroup model = null; try { _logger.Enter($"{nameof(sid)}={sid} {nameof(rowVersion)}={rowVersion}"); DBAccessor.Models.DtDeliveryGroup entity = new DBAccessor.Models.DtDeliveryGroup() { Sid = sid, RowVersion = rowVersion }; _dbPolly.Execute(() => { using (DBAccessor.Models.RmsDbContext db = new DBAccessor.Models.RmsDbContext(_appSettings)) { // 指定した配信ステータスSIDを検索し、未配信状態であるかチェックする // 備考:該当する配信グループが0個(Whereの結果が空のリスト)の場合、Allは必ずtrueを返す // そのためすべての配信ステータスが未配信状態であると見なされ、isNotStart=trueとなることに注意 var isNotStart = db.DtDeliveryGroup .Where(x => x.Sid == sid) .Include(x => x.DeliveryGroupStatusS) .All(x => x.DeliveryGroupStatusS.Code.Equals(Utility.Const.DeliveryGroupStatus.NotStarted)); if (!isNotStart) { throw new RmsCannotChangeDeliveredFileException(string.Format("配信前状態ではないDT_DELIVERY_GROUPテーブルのレコードをDeleteしようとしました。(DT_DELIVERY_GROUP.SID = {0})", sid)); } // SIDが一致するレコードが存在しない場合はDeleteを実行しない // (存在しないSIDに対してDeleteを実行してしまうと、DbUpdateConcurrencyExceptionが発生してしまい、 // RowVersion競合とNot Foundとの区別ができないため) if (db.DtDeliveryGroup.Any(x => x.Sid == sid)) { db.DtDeliveryGroup.Attach(entity); db.DtDeliveryGroup.Remove(entity); if (db.SaveChanges() > 0) { model = entity.ToModel(); } } } }); return(model); } catch (DbUpdateConcurrencyException e) { // RowVersion衝突が起きた throw new RmsConflictException("DT_DELIVERY_GROUPテーブルのDeleteで競合が発生しました。", e); } catch (RmsException) { throw; } catch (Exception e) { throw new RmsException("DT_DELIVERY_GROUPテーブルのDeleteに失敗しました。", e); } finally { _logger.LeaveJson("{0}", model); } }