static async Task AddOrUpdateAsync(BiblioCacheContext context, EntityItem item) { try { // 保存到本地数据库 context.Entities.Add(item); await context.SaveChangesAsync(); } catch (Exception ex) { SqliteException sqlite_exception = ex.InnerException as SqliteException; if (sqlite_exception != null && sqlite_exception.SqliteErrorCode == 19) { // PII 发生重复了 goto UPDATE; } else { throw ex; } } UPDATE: // 更新到本地数据库 context.Entities.Update(item); await context.SaveChangesAsync(); }
// 获得册记录信息和书目摘要信息 // parameters: // style 风格。network 表示只从网络获取册记录;否则优先从本地获取,本地没有再从网络获取册记录。无论如何,书目摘要都是尽量从本地获取 // .Value // 0 没有找到 // 1 找到 public static async Task <GetEntityDataResult> GetEntityDataAsync(string pii, string style) { bool network = StringUtil.IsInList("network", style); try { using (var releaser = await _channelLimit.EnterAsync()) { SipChannel channel = await GetChannelAsync(); try { GetEntityDataResult result = null; List <NormalResult> errors = new List <NormalResult>(); EntityItem entity_record = null; // *** // 第一步:获取册记录 { // 再尝试从 dp2library 服务器获取 // TODO: ItemXml 和 BiblioSummary 可以考虑在本地缓存一段时间 int nRedoCount = 0; REDO_GETITEMINFO: var get_result = await _channel.GetItemInfoAsync("", pii); if (get_result.Value == -1) { errors.Add(new NormalResult { Value = -1, ErrorInfo = get_result.ErrorInfo, ErrorCode = get_result.ErrorCode }); } else if (get_result.Result.CirculationStatus_2 == "01") { errors.Add(new NormalResult { Value = -1, ErrorInfo = get_result.Result.AF_ScreenMessage_o, ErrorCode = get_result.Result.CirculationStatus_2 }); } else if (get_result.Result.CirculationStatus_2 == "13") { errors.Add(new NormalResult { Value = -1, ErrorInfo = get_result.Result.AF_ScreenMessage_o, ErrorCode = "itemNotFound" }); } else { XmlDocument itemdom = new XmlDocument(); itemdom.LoadXml("<root />"); string state = ""; if (get_result.Result.CirculationStatus_2 == "12") { state = "丢失"; } DomUtil.SetElementText(itemdom.DocumentElement, "state", state); DomUtil.SetElementText(itemdom.DocumentElement, "barcode", get_result.Result.AB_ItemIdentifier_r); DomUtil.SetElementText(itemdom.DocumentElement, "location", get_result.Result.AQ_PermanentLocation_o); DomUtil.SetElementText(itemdom.DocumentElement, "currentLocation", get_result.Result.AP_CurrentLocation_o); DomUtil.SetElementText(itemdom.DocumentElement, "accessNo", get_result.Result.CH_ItemProperties_o); // 借书时间 { string borrowDateString = get_result.Result.CM_HoldPickupDate_18; if (string.IsNullOrEmpty(borrowDateString) == false) { if (DateTime.TryParseExact(borrowDateString, "yyyyMMdd HHmmss", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime borrowDate)) { DomUtil.SetElementText(itemdom.DocumentElement, "borrowDate", DateTimeUtil.Rfc1123DateTimeStringEx(borrowDate)); DomUtil.SetElementText(itemdom.DocumentElement, "borrower", "***"); } else { // 报错,时间字符串格式错误,无法解析 } } } // 应还书时间 { string returnningDateString = get_result.Result.AH_DueDate_o; if (string.IsNullOrEmpty(returnningDateString) == false) { if (DateTime.TryParseExact(returnningDateString, DateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime returningDate)) { DomUtil.SetElementText(itemdom.DocumentElement, "returningDate", DateTimeUtil.Rfc1123DateTimeStringEx(returningDate)); } else { // 报错,时间字符串格式错误,无法解析 } } } result = new GetEntityDataResult { Value = 1, ItemXml = itemdom.OuterXml, ItemRecPath = get_result.Result.AB_ItemIdentifier_r, Title = get_result.Result.AJ_TitleIdentifier_r, }; /* * // 保存到本地数据库 * await AddOrUpdateAsync(context, new EntityItem * { * PII = pii, * Xml = item_xml, * RecPath = item_recpath, * Timestamp = timestamp, * }); */ } } // *** /// 第二步:获取书目摘要 // 完全成功 if (result != null && errors.Count == 0) { return(result); } if (result == null) { return new GetEntityDataResult { Value = errors[0].Value, ErrorInfo = errors[0].ErrorInfo, ErrorCode = errors[0].ErrorCode } } ; result.ErrorInfo = errors[0].ErrorInfo; result.ErrorCode = errors[0].ErrorCode; return(result); } finally { ReturnChannel(channel); } } } catch (Exception ex) { WpfClientInfo.WriteErrorLog($"GetEntityDataAsync() 出现异常: {ExceptionUtil.GetDebugText(ex)}"); return(new GetEntityDataResult { Value = -1, ErrorInfo = $"GetEntityDataAsync() 出现异常: {ex.Message}", ErrorCode = ex.GetType().ToString() }); } }
// 获得册记录信息和书目摘要信息 // parameters: // style 风格。network 表示只从网络获取册记录;否则优先从本地获取,本地没有再从网络获取册记录。无论如何,书目摘要都是尽量从本地获取 // .Value // 0 没有找到 // 1 找到 public static async Task <GetEntityDataResult> GetEntityDataAsync(string pii, string style) { bool network = StringUtil.IsInList("network", style); try { using (var releaser = await _channelLimit.EnterAsync()) using (BiblioCacheContext context = new BiblioCacheContext()) { if (_cacheDbCreated == false) { context.Database.EnsureCreated(); _cacheDbCreated = true; } LibraryChannel channel = App.CurrentApp.GetChannel(); TimeSpan old_timeout = channel.Timeout; channel.Timeout = TimeSpan.FromSeconds(10); try { GetEntityDataResult result = null; List <NormalResult> errors = new List <NormalResult>(); EntityItem entity_record = null; // *** // 第一步:获取册记录 if (network == false) { // 先尝试从本地实体库中获得记录 entity_record = context.Entities.Where(o => o.PII == pii).FirstOrDefault(); // EntityItem entity_record = null; // testing } if (entity_record != null) { result = new GetEntityDataResult { Value = 1, ItemXml = entity_record.Xml, ItemRecPath = entity_record.RecPath, Title = "", } } ; else { // 再尝试从 dp2library 服务器获取 // TODO: ItemXml 和 BiblioSummary 可以考虑在本地缓存一段时间 int nRedoCount = 0; REDO_GETITEMINFO: long lRet = channel.GetItemInfo(null, "item", pii, "", "xml", out string item_xml, out string item_recpath, out byte[] timestamp, "", out _, out _, out string strError); if (lRet == -1) { if ((channel.ErrorCode == ErrorCode.RequestError || channel.ErrorCode == ErrorCode.RequestTimeOut) && nRedoCount < 2) { nRedoCount++; goto REDO_GETITEMINFO; } // TODO: 这里不着急返回,还需要尝试获得书目摘要 errors.Add(new NormalResult { Value = -1, ErrorInfo = strError, ErrorCode = channel.ErrorCode.ToString() }); /* * return new GetEntityDataResult * { * Value = -1, * ErrorInfo = strError, * ErrorCode = channel.ErrorCode.ToString() * }; */ } else { result = new GetEntityDataResult { Value = 1, ItemXml = item_xml, ItemRecPath = item_recpath, Title = "", }; // 保存到本地数据库 await AddOrUpdateAsync(context, new EntityItem { PII = pii, Xml = item_xml, RecPath = item_recpath, Timestamp = timestamp, }); #if NO context.Entities.Add(new EntityItem { PII = pii, Xml = item_xml, RecPath = item_recpath, Timestamp = timestamp, }); try { await context.SaveChangesAsync(); } catch (Exception ex) { SqliteException sqlite_exception = ex.InnerException as SqliteException; if (sqlite_exception != null && sqlite_exception.SqliteErrorCode == 19) { // PII 发生重复了 } else { throw ex; } } #endif } } // *** /// 第二步:获取书目摘要 // 先尝试从本地书目库中获取书目摘要 var item = context.BiblioSummaries.Where(o => o.PII == pii).FirstOrDefault(); if (item != null && string.IsNullOrEmpty(item.BiblioSummary) == false) { if (result == null) { result = new GetEntityDataResult(); } result.Title = item.BiblioSummary; } else { // 从 dp2library 服务器获取书目摘要 int nRedoCount = 0; REDO_GETBIBLIOSUMMARY: long lRet = channel.GetBiblioSummary( null, pii, "", // strConfirmItemRecPath, null, out _, out string strSummary, out string strError); if (lRet == -1) { if ((channel.ErrorCode == ErrorCode.RequestError || channel.ErrorCode == ErrorCode.RequestTimeOut) && nRedoCount < 2) { nRedoCount++; goto REDO_GETBIBLIOSUMMARY; } errors.Add(new NormalResult { Value = -1, ErrorInfo = strError, ErrorCode = channel.ErrorCode.ToString() }); /* * return new GetEntityDataResult * { * Value = -1, * ErrorInfo = strError, * ErrorCode = channel.ErrorCode.ToString(), * }; */ } else { strSummary = strSummary?.Replace(". -- ", "\r\n"); // .Replace("/", "\r\n"); if (result == null) { result = new GetEntityDataResult(); } result.Title = strSummary; // 存入数据库备用 if (lRet == 1 && string.IsNullOrEmpty(strSummary) == false) { try { var exist_item = context.BiblioSummaries.Where(o => o.PII == pii).FirstOrDefault(); if (exist_item != null) { if (exist_item.BiblioSummary != strSummary) { exist_item.BiblioSummary = strSummary; context.BiblioSummaries.Update(exist_item); } } else { context.BiblioSummaries.Add(new BiblioSummaryItem { PII = pii, BiblioSummary = strSummary }); } await context.SaveChangesAsync(); } catch (Exception ex) { WpfClientInfo.WriteErrorLog($"GetEntityDataAsync() 中保存 summary 时(PII 为 '{pii}')出现异常:{ExceptionUtil.GetDebugText(ex)}"); } } } /* * return new GetEntityDataResult * { * Value = (int)lRet, * ItemXml = item_xml, * ItemRecPath = item_recpath, * Title = strSummary, * ErrorInfo = strError, * ErrorCode = channel.ErrorCode.ToString() * }; */ } // 完全成功 if (result != null && errors.Count == 0) { return(result); } if (result == null) { return new GetEntityDataResult { Value = errors[0].Value, ErrorInfo = errors[0].ErrorInfo, ErrorCode = errors[0].ErrorCode } } ; result.ErrorInfo = errors[0].ErrorInfo; result.ErrorCode = errors[0].ErrorCode; return(result); } finally { channel.Timeout = old_timeout; App.CurrentApp.ReturnChannel(channel); } } } catch (Exception ex) { WpfClientInfo.WriteErrorLog($"GetEntityDataAsync() 出现异常: {ExceptionUtil.GetDebugText(ex)}"); return(new GetEntityDataResult { Value = -1, ErrorInfo = $"GetEntityDataAsync() 出现异常: {ex.Message}", ErrorCode = ex.GetType().ToString() }); } }