Merge pull request #876 from ONLYOFFICE/feature/rooms-counter-new
Feature/rooms counter new
This commit is contained in:
commit
669a5116d5
@ -41,10 +41,10 @@ public interface ITagDao<T>
|
||||
IAsyncEnumerable<Tag> GetTagsAsync(string[] names, TagType tagType);
|
||||
IAsyncEnumerable<TagInfo> GetTagsInfoAsync(string searchText, TagType tagType, bool byName, int from = 0, int count = 0);
|
||||
IAsyncEnumerable<TagInfo> GetTagsInfoAsync(IEnumerable<string> names);
|
||||
IEnumerable<Tag> SaveTags(IEnumerable<Tag> tag);
|
||||
IEnumerable<Tag> SaveTags(IEnumerable<Tag> tag, Guid createdBy = default);
|
||||
IEnumerable<Tag> SaveTags(Tag tag);
|
||||
Task<TagInfo> SaveTagInfoAsync(TagInfo tagInfo);
|
||||
void UpdateNewTags(IEnumerable<Tag> tag);
|
||||
void UpdateNewTags(IEnumerable<Tag> tag, Guid createdBy = default);
|
||||
void UpdateNewTags(Tag tag);
|
||||
Task RemoveTagsAsync(IEnumerable<int> tagsIds);
|
||||
Task RemoveTagsAsync(FileEntry<T> entry, IEnumerable<int> tagsIds);
|
||||
|
@ -301,7 +301,7 @@ internal class TagDao<T> : AbstractDao, ITagDao<T>
|
||||
return _mapper.Map<DbFilesTag, TagInfo>(tag.Entity);
|
||||
}
|
||||
|
||||
public IEnumerable<Tag> SaveTags(IEnumerable<Tag> tags)
|
||||
public IEnumerable<Tag> SaveTags(IEnumerable<Tag> tags, Guid createdBy = default)
|
||||
{
|
||||
var result = new List<Tag>();
|
||||
|
||||
@ -332,7 +332,7 @@ internal class TagDao<T> : AbstractDao, ITagDao<T>
|
||||
var createOn = _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow());
|
||||
var cacheTagId = new Dictionary<string, int>();
|
||||
|
||||
result.AddRange(tags.Select(t => SaveTagAsync(t, cacheTagId, createOn).Result));
|
||||
result.AddRange(tags.Select(t => SaveTagAsync(t, cacheTagId, createOn, createdBy).Result));
|
||||
|
||||
tx.Commit();
|
||||
});
|
||||
@ -410,7 +410,7 @@ internal class TagDao<T> : AbstractDao, ITagDao<T>
|
||||
filesDbContext.SaveChanges();
|
||||
}
|
||||
|
||||
private async Task<Tag> SaveTagAsync(Tag t, Dictionary<string, int> cacheTagId, DateTime createOn)
|
||||
private async Task<Tag> SaveTagAsync(Tag t, Dictionary<string, int> cacheTagId, DateTime createOn, Guid createdBy = default)
|
||||
{
|
||||
using var filesDbContext = _dbContextFactory.CreateDbContext();
|
||||
|
||||
@ -452,7 +452,7 @@ internal class TagDao<T> : AbstractDao, ITagDao<T>
|
||||
TagId = id,
|
||||
EntryId = (await MappingIDAsync(t.EntryId, true)).ToString(),
|
||||
EntryType = t.EntryType,
|
||||
CreateBy = _authContext.CurrentAccount.ID,
|
||||
CreateBy = createdBy != default ? createdBy : _authContext.CurrentAccount.ID,
|
||||
CreateOn = createOn,
|
||||
Count = t.Count
|
||||
};
|
||||
@ -463,7 +463,7 @@ internal class TagDao<T> : AbstractDao, ITagDao<T>
|
||||
return t;
|
||||
}
|
||||
|
||||
public void UpdateNewTags(IEnumerable<Tag> tags)
|
||||
public void UpdateNewTags(IEnumerable<Tag> tags, Guid createdBy = default)
|
||||
{
|
||||
if (tags == null || !tags.Any())
|
||||
{
|
||||
@ -483,7 +483,7 @@ internal class TagDao<T> : AbstractDao, ITagDao<T>
|
||||
|
||||
foreach (var tag in tags)
|
||||
{
|
||||
UpdateNewTagsInDbAsync(tag, createOn).Wait();
|
||||
UpdateNewTagsInDbAsync(tag, createOn, createdBy).Wait();
|
||||
}
|
||||
|
||||
tx.Commit();
|
||||
@ -506,17 +506,17 @@ internal class TagDao<T> : AbstractDao, ITagDao<T>
|
||||
}
|
||||
}
|
||||
|
||||
private Task UpdateNewTagsInDbAsync(Tag tag, DateTime createOn)
|
||||
private Task UpdateNewTagsInDbAsync(Tag tag, DateTime createOn, Guid createdBy = default)
|
||||
{
|
||||
if (tag == null)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
return InternalUpdateNewTagsInDbAsync(tag, createOn);
|
||||
return InternalUpdateNewTagsInDbAsync(tag, createOn, createdBy);
|
||||
}
|
||||
|
||||
private async Task InternalUpdateNewTagsInDbAsync(Tag tag, DateTime createOn)
|
||||
private async Task InternalUpdateNewTagsInDbAsync(Tag tag, DateTime createOn, Guid createdBy = default)
|
||||
{
|
||||
using var filesDbContext = _dbContextFactory.CreateDbContext();
|
||||
var mappedId = (await MappingIDAsync(tag.EntryId)).ToString();
|
||||
@ -527,7 +527,7 @@ internal class TagDao<T> : AbstractDao, ITagDao<T>
|
||||
|
||||
foreach (var f in forUpdate)
|
||||
{
|
||||
f.CreateBy = _authContext.CurrentAccount.ID;
|
||||
f.CreateBy = createdBy != default ? createdBy : _authContext.CurrentAccount.ID;
|
||||
f.CreateOn = createOn;
|
||||
f.Count = tag.Count;
|
||||
}
|
||||
@ -967,7 +967,7 @@ internal class TagDao<T> : AbstractDao, ITagDao<T>
|
||||
tempTags = tempTags.Concat(_projectsQuery(filesDbContext, tenantId, subject));
|
||||
}
|
||||
|
||||
if (!deepSearch)
|
||||
if (!deepSearch && parentFolder.RootFolderType != FolderType.VirtualRooms)
|
||||
{
|
||||
await foreach (var e in tempTags)
|
||||
{
|
||||
@ -1022,6 +1022,7 @@ internal class TagDao<T> : AbstractDao, ITagDao<T>
|
||||
result = result.Concat(_newTagsForSBoxQuery(filesDbContext, tenantId, subject, thirdpartyFolderIds));
|
||||
}
|
||||
}
|
||||
|
||||
if (parentFolder.FolderType == FolderType.VirtualRooms)
|
||||
{
|
||||
result = result.Concat(_newTagsThirdpartyRoomsQuery(filesDbContext, tenantId, subject));
|
||||
|
@ -1592,7 +1592,7 @@ public class FileStorageService<T> //: IFileStorageService
|
||||
var folderDao = GetFolderDao();
|
||||
folder = await folderDao.GetFolderAsync(folderId);
|
||||
|
||||
var result = await _fileMarker.MarkedItemsAsync(folder).ToListAsync();
|
||||
var result = await _fileMarker.MarkedItemsAsync(folder).Where(e => e.FileEntryType == FileEntryType.File).ToListAsync();
|
||||
|
||||
result = new List<FileEntry>(_entryManager.SortEntries<T>(result, new OrderBy(SortedByType.DateAndTime, false)));
|
||||
|
||||
|
@ -234,12 +234,14 @@ public class FileSecurity : IFileSecurity
|
||||
var shares = await GetSharesAsync(entry);
|
||||
var copyShares = shares.ToList();
|
||||
|
||||
FileShareRecord defaultShareRecord;
|
||||
FileShareRecord[] defaultRecords;
|
||||
|
||||
switch (entry.RootFolderType)
|
||||
{
|
||||
case FolderType.COMMON:
|
||||
defaultShareRecord = new FileShareRecord
|
||||
defaultRecords = new[]
|
||||
{
|
||||
new FileShareRecord
|
||||
{
|
||||
Level = int.MaxValue,
|
||||
EntryId = entry.Id,
|
||||
@ -248,10 +250,13 @@ public class FileSecurity : IFileSecurity
|
||||
Subject = Constants.GroupEveryone.ID,
|
||||
TenantId = _tenantManager.GetCurrentTenant().Id,
|
||||
Owner = _authContext.CurrentAccount.ID
|
||||
}
|
||||
};
|
||||
|
||||
if (!shares.Any())
|
||||
{
|
||||
var defaultShareRecord = defaultRecords.FirstOrDefault();
|
||||
|
||||
if ((defaultShareRecord.Share == FileShare.Read && action == FilesSecurityActions.Read) ||
|
||||
(defaultShareRecord.Share == FileShare.ReadWrite))
|
||||
{
|
||||
@ -265,7 +270,9 @@ public class FileSecurity : IFileSecurity
|
||||
break;
|
||||
|
||||
case FolderType.USER:
|
||||
defaultShareRecord = new FileShareRecord
|
||||
defaultRecords = new[]
|
||||
{
|
||||
new FileShareRecord
|
||||
{
|
||||
Level = int.MaxValue,
|
||||
EntryId = entry.Id,
|
||||
@ -274,6 +281,7 @@ public class FileSecurity : IFileSecurity
|
||||
Subject = entry.RootCreateBy,
|
||||
TenantId = _tenantManager.GetCurrentTenant().Id,
|
||||
Owner = entry.RootCreateBy
|
||||
}
|
||||
};
|
||||
|
||||
if (!shares.Any())
|
||||
@ -283,11 +291,12 @@ public class FileSecurity : IFileSecurity
|
||||
entry.RootCreateBy
|
||||
};
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case FolderType.Privacy:
|
||||
defaultShareRecord = new FileShareRecord
|
||||
defaultRecords = new[]
|
||||
{
|
||||
new FileShareRecord
|
||||
{
|
||||
Level = int.MaxValue,
|
||||
EntryId = entry.Id,
|
||||
@ -296,6 +305,7 @@ public class FileSecurity : IFileSecurity
|
||||
Subject = entry.RootCreateBy,
|
||||
TenantId = _tenantManager.GetCurrentTenant().Id,
|
||||
Owner = entry.RootCreateBy
|
||||
}
|
||||
};
|
||||
|
||||
if (!shares.Any())
|
||||
@ -305,7 +315,6 @@ public class FileSecurity : IFileSecurity
|
||||
entry.RootCreateBy
|
||||
};
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case FolderType.BUNCH:
|
||||
@ -327,11 +336,13 @@ public class FileSecurity : IFileSecurity
|
||||
}
|
||||
|
||||
// TODO: For Projects and other
|
||||
defaultShareRecord = null;
|
||||
defaultRecords = null;
|
||||
break;
|
||||
|
||||
case FolderType.VirtualRooms:
|
||||
defaultShareRecord = new FileShareRecord
|
||||
defaultRecords = new[]
|
||||
{
|
||||
new FileShareRecord
|
||||
{
|
||||
Level = int.MaxValue,
|
||||
EntryId = entry.Id,
|
||||
@ -340,30 +351,41 @@ public class FileSecurity : IFileSecurity
|
||||
Subject = WebItemManager.DocumentsProductID,
|
||||
TenantId = _tenantManager.GetCurrentTenant().Id,
|
||||
Owner = entry.RootCreateBy
|
||||
},
|
||||
new FileShareRecord
|
||||
{
|
||||
Level = int.MaxValue,
|
||||
EntryId = entry.Id,
|
||||
EntryType = entry.FileEntryType,
|
||||
Share = FileShare.Read,
|
||||
Subject = Constants.GroupAdmin.ID,
|
||||
TenantId = _tenantManager.GetCurrentTenant().Id,
|
||||
Owner = entry.RootCreateBy
|
||||
}
|
||||
};
|
||||
|
||||
if (!shares.Any())
|
||||
{
|
||||
if ((defaultShareRecord.Share == FileShare.Read && action == FilesSecurityActions.Read) ||
|
||||
(defaultShareRecord.Share == FileShare.ReadWrite))
|
||||
var users = new List<Guid>();
|
||||
|
||||
foreach (var defaultRecord in defaultRecords)
|
||||
{
|
||||
return _userManager.GetUsersByGroup(defaultShareRecord.Subject)
|
||||
.Where(x => x.Status == EmployeeStatus.Active).Select(y => y.Id).Distinct();
|
||||
users.AddRange(_userManager.GetUsersByGroup(defaultRecord.Subject).Where(x => x.Status == EmployeeStatus.Active).Select(y => y.Id));
|
||||
}
|
||||
|
||||
return Enumerable.Empty<Guid>();
|
||||
return users.Distinct();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
defaultShareRecord = null;
|
||||
defaultRecords = null;
|
||||
break;
|
||||
}
|
||||
|
||||
if (defaultShareRecord != null)
|
||||
if (defaultRecords != null)
|
||||
{
|
||||
shares = shares.Concat(new[] { defaultShareRecord });
|
||||
shares = shares.Concat(defaultRecords);
|
||||
}
|
||||
|
||||
var manyShares = shares.SelectMany(x =>
|
||||
@ -378,8 +400,7 @@ public class FileSecurity : IFileSecurity
|
||||
}
|
||||
|
||||
return new[] { x.Subject };
|
||||
})
|
||||
.Distinct();
|
||||
}).Distinct();
|
||||
|
||||
var result = new List<Guid>();
|
||||
|
||||
|
@ -594,7 +594,7 @@ internal abstract class ThirdPartyProviderDao<T> : ThirdPartyProviderDao, IDispo
|
||||
return Task.FromResult(tagInfo);
|
||||
}
|
||||
|
||||
public IEnumerable<Tag> SaveTags(IEnumerable<Tag> tag)
|
||||
public IEnumerable<Tag> SaveTags(IEnumerable<Tag> tag, Guid createdBy = default)
|
||||
{
|
||||
return new List<Tag>();
|
||||
}
|
||||
@ -604,7 +604,7 @@ internal abstract class ThirdPartyProviderDao<T> : ThirdPartyProviderDao, IDispo
|
||||
return new List<Tag>();
|
||||
}
|
||||
|
||||
public void UpdateNewTags(IEnumerable<Tag> tag)
|
||||
public void UpdateNewTags(IEnumerable<Tag> tag, Guid createdBy = default)
|
||||
{
|
||||
}
|
||||
|
||||
@ -645,7 +645,7 @@ internal abstract class ThirdPartyProviderDao<T> : ThirdPartyProviderDao, IDispo
|
||||
|
||||
var filesDbContext = _dbContextFactory.CreateDbContext();
|
||||
var entryIDs = await filesDbContext.ThirdpartyIdMapping
|
||||
.Where(r => r.Id.StartsWith(parentFolder.Id))
|
||||
.Where(r => r.Id.StartsWith(PathPrefix))
|
||||
.Select(r => r.HashId)
|
||||
.ToListAsync();
|
||||
|
||||
|
@ -83,9 +83,9 @@ internal class ProviderTagDao : ProviderDaoBase, ITagDao<string>
|
||||
return _tagDao.GetTagsAsync(names, tagType);
|
||||
}
|
||||
|
||||
public IEnumerable<Tag> SaveTags(IEnumerable<Tag> tag)
|
||||
public IEnumerable<Tag> SaveTags(IEnumerable<Tag> tag, Guid createdBy = default)
|
||||
{
|
||||
return _tagDao.SaveTags(tag);
|
||||
return _tagDao.SaveTags(tag, createdBy);
|
||||
}
|
||||
|
||||
public IEnumerable<Tag> SaveTags(Tag tag)
|
||||
@ -93,9 +93,9 @@ internal class ProviderTagDao : ProviderDaoBase, ITagDao<string>
|
||||
return _tagDao.SaveTags(tag);
|
||||
}
|
||||
|
||||
public void UpdateNewTags(IEnumerable<Tag> tag)
|
||||
public void UpdateNewTags(IEnumerable<Tag> tag, Guid createdBy = default)
|
||||
{
|
||||
_tagDao.UpdateNewTags(tag);
|
||||
_tagDao.UpdateNewTags(tag, createdBy);
|
||||
}
|
||||
|
||||
public void UpdateNewTags(Tag tag)
|
||||
|
@ -722,10 +722,10 @@ public class EntryManager
|
||||
var tagDao = _daoFactory.GetTagDao<int>();
|
||||
var tags = tagDao.GetTagsAsync(_authContext.CurrentAccount.ID, TagType.Favorite);
|
||||
|
||||
var fileIdsInt = Enumerable.Empty<int>();
|
||||
var fileIdsString = Enumerable.Empty<string>();
|
||||
var folderIdsInt = Enumerable.Empty<int>();
|
||||
var folderIdsString = Enumerable.Empty<string>();
|
||||
var fileIdsInt = new List<int>();
|
||||
var fileIdsString = new List<string>();
|
||||
var folderIdsInt = new List<int>();
|
||||
var folderIdsString = new List<string>();
|
||||
|
||||
await foreach (var tag in tags)
|
||||
{
|
||||
@ -733,22 +733,22 @@ public class EntryManager
|
||||
{
|
||||
if (tag.EntryId is int)
|
||||
{
|
||||
fileIdsInt.Append((int)tag.EntryId);
|
||||
fileIdsInt.Add((int)tag.EntryId);
|
||||
}
|
||||
else if (tag.EntryId is string)
|
||||
{
|
||||
fileIdsString.Append((string)tag.EntryId);
|
||||
fileIdsString.Add((string)tag.EntryId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tag.EntryId is int)
|
||||
{
|
||||
folderIdsInt.Append((int)tag.EntryId);
|
||||
folderIdsInt.Add((int)tag.EntryId);
|
||||
}
|
||||
else if (tag.EntryId is string)
|
||||
{
|
||||
folderIdsString.Append((string)tag.EntryId);
|
||||
folderIdsString.Add((string)tag.EntryId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ public class FileMarker
|
||||
{
|
||||
private readonly ICache _cache;
|
||||
|
||||
private const string _cacheKeyFormat = "MarkedAsNew/{0}/folder_{1}";
|
||||
private const string CacheKeyFormat = "MarkedAsNew/{0}/folder_{1}";
|
||||
|
||||
private readonly TenantManager _tenantManager;
|
||||
private readonly UserManager _userManager;
|
||||
@ -166,6 +166,24 @@ public class FileMarker
|
||||
if (obj.FileEntry.ProviderEntry)
|
||||
{
|
||||
userIDs = userIDs.Where(u => !_userManager.IsVisitor(u)).ToList();
|
||||
|
||||
if (obj.FileEntry.RootFolderType == FolderType.VirtualRooms)
|
||||
{
|
||||
var parents = new List<Folder<T>>();
|
||||
|
||||
foreach (var folder in parentFolders)
|
||||
{
|
||||
if (DocSpaceHelper.IsRoom(folder.FolderType))
|
||||
{
|
||||
parents.Add(folder);
|
||||
break;
|
||||
}
|
||||
|
||||
parents.Add(folder);
|
||||
}
|
||||
|
||||
parentFolders = parents;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var parentFolder in parentFolders)
|
||||
@ -259,7 +277,25 @@ public class FileMarker
|
||||
else if (obj.FileEntry.RootFolderType == FolderType.VirtualRooms)
|
||||
{
|
||||
var virtualRoomsFolderId = await _globalFolder.GetFolderVirtualRoomsAsync(_daoFactory);
|
||||
userIDs.ForEach(userID => RemoveFromCahce(virtualRoomsFolderId, userID));
|
||||
|
||||
if (obj.FileEntry.ProviderEntry)
|
||||
{
|
||||
var virtualRoomsFolder = await _daoFactory.GetFolderDao<int>().GetFolderAsync(virtualRoomsFolderId);
|
||||
|
||||
userIDs.ForEach(userID =>
|
||||
{
|
||||
if (userEntriesData.TryGetValue(userID, out var value))
|
||||
{
|
||||
value.Add(virtualRoomsFolder);
|
||||
}
|
||||
else
|
||||
{
|
||||
userEntriesData.Add(userID, new List<FileEntry> { virtualRoomsFolder });
|
||||
}
|
||||
|
||||
RemoveFromCahce(virtualRoomsFolderId, userID);
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (obj.FileEntry.RootFolderType == FolderType.Privacy)
|
||||
{
|
||||
@ -322,12 +358,12 @@ public class FileMarker
|
||||
|
||||
if (updateTags.Count > 0)
|
||||
{
|
||||
tagDao.UpdateNewTags(updateTags);
|
||||
tagDao.UpdateNewTags(updateTags, obj.CurrentAccountId);
|
||||
}
|
||||
|
||||
if (newTags.Count > 0)
|
||||
{
|
||||
tagDao.SaveTags(newTags);
|
||||
tagDao.SaveTags(newTags, obj.CurrentAccountId);
|
||||
}
|
||||
|
||||
async Task GetNewTagsAsync<T1>(Guid userID, List<FileEntry<T1>> entries)
|
||||
@ -628,7 +664,8 @@ public class FileMarker
|
||||
|
||||
if (Equals(folder.Id, _globalFolder.GetFolderMy(this, _daoFactory)) ||
|
||||
Equals(folder.Id, await _globalFolder.GetFolderCommonAsync(this, _daoFactory)) ||
|
||||
Equals(folder.Id, await _globalFolder.GetFolderShareAsync(_daoFactory)))
|
||||
Equals(folder.Id, await _globalFolder.GetFolderShareAsync(_daoFactory)) ||
|
||||
Equals(folder.Id, await _globalFolder.GetFolderVirtualRoomsAsync(_daoFactory)))
|
||||
{
|
||||
var folderTags = tags.Where(tag => tag.EntryType == FileEntryType.Folder && (tag.EntryId is string));
|
||||
|
||||
@ -764,8 +801,12 @@ public class FileMarker
|
||||
: totalTags.FirstOrDefault(tag => tag.EntryType == FileEntryType.Folder && Equals(tag.EntryId, parent.Id));
|
||||
|
||||
totalTags = totalTags.Where(e => e != parentFolderTag).ToList();
|
||||
|
||||
var countSubNew = 0;
|
||||
totalTags.ForEach(tag => countSubNew += tag.Count);
|
||||
totalTags.ForEach(tag =>
|
||||
{
|
||||
countSubNew += tag.Count;
|
||||
});
|
||||
|
||||
if (parentFolderTag == null)
|
||||
{
|
||||
@ -773,6 +814,11 @@ public class FileMarker
|
||||
parentFolderTag.Id = -1;
|
||||
}
|
||||
|
||||
if (parent.FolderType != FolderType.VirtualRooms && parent.RootFolderType == FolderType.VirtualRooms && parent.ProviderEntry)
|
||||
{
|
||||
countSubNew = parentFolderTag.Count;
|
||||
}
|
||||
|
||||
if (parentFolderTag.Count != countSubNew)
|
||||
{
|
||||
if (countSubNew > 0)
|
||||
@ -874,13 +920,13 @@ public class FileMarker
|
||||
|
||||
private void InsertToCahce(object folderId, int count)
|
||||
{
|
||||
var key = string.Format(_cacheKeyFormat, _authContext.CurrentAccount.ID, folderId);
|
||||
var key = string.Format(CacheKeyFormat, _authContext.CurrentAccount.ID, folderId);
|
||||
_cache.Insert(key, count.ToString(), TimeSpan.FromMinutes(10));
|
||||
}
|
||||
|
||||
private int GetCountFromCahce(object folderId)
|
||||
{
|
||||
var key = string.Format(_cacheKeyFormat, _authContext.CurrentAccount.ID, folderId);
|
||||
var key = string.Format(CacheKeyFormat, _authContext.CurrentAccount.ID, folderId);
|
||||
var count = _cache.Get<string>(key);
|
||||
|
||||
return count == null ? -1 : int.Parse(count);
|
||||
@ -893,7 +939,7 @@ public class FileMarker
|
||||
|
||||
private void RemoveFromCahce(object folderId, Guid userId)
|
||||
{
|
||||
var key = string.Format(_cacheKeyFormat, userId, folderId);
|
||||
var key = string.Format(CacheKeyFormat, userId, folderId);
|
||||
_cache.Remove(key);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user