dir 增加字段
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
eafceeb5d1
commit
875a3668c1
|
@ -61,77 +61,89 @@ namespace IRaCIS.Core.Application.Helper
|
||||||
foreach (var item in list.OrderBy(t => t.SeriesNumber).ThenBy(t => t.InstanceNumber))
|
foreach (var item in list.OrderBy(t => t.SeriesNumber).ThenBy(t => t.InstanceNumber))
|
||||||
{
|
{
|
||||||
var dicomUid = DicomUID.Enumerate().FirstOrDefault(uid => uid.UID == item.TransferSytaxUID);
|
var dicomUid = DicomUID.Enumerate().FirstOrDefault(uid => uid.UID == item.TransferSytaxUID);
|
||||||
var ts = DicomTransferSyntax.Query(dicomUid);
|
|
||||||
|
|
||||||
var dataset = new DicomDataset(ts)
|
if (dicomUid != null)
|
||||||
{
|
{
|
||||||
{ DicomTag.PatientID, item.PatientId ?? string.Empty },
|
var ts = DicomTransferSyntax.Query(dicomUid);
|
||||||
{ DicomTag.PatientName, item.PatientName ?? string.Empty },
|
|
||||||
{ DicomTag.PatientBirthDate, item.PatientBirthDate ?? string.Empty },
|
|
||||||
{ DicomTag.PatientSex, item.PatientSex ?? string.Empty },
|
|
||||||
|
|
||||||
{ DicomTag.StudyInstanceUID, item.StudyInstanceUid ?? string.Empty },
|
var dataset = new DicomDataset(ts)
|
||||||
{ DicomTag.StudyID, item.StudyId ?? string.Empty },
|
{
|
||||||
{ DicomTag.StudyDate, item.DicomStudyDate ?? string.Empty },
|
{ DicomTag.PatientID, item.PatientId ?? string.Empty },
|
||||||
{ DicomTag.StudyTime, item.DicomStudyTime ?? string.Empty },
|
{ DicomTag.PatientName, item.PatientName ?? string.Empty },
|
||||||
{ DicomTag.AccessionNumber, item.AccessionNumber ?? string.Empty },
|
{ DicomTag.PatientBirthDate, item.PatientBirthDate ?? string.Empty },
|
||||||
{ DicomTag.StudyDescription, item.StudyDescription ?? string.Empty },
|
{ DicomTag.PatientSex, item.PatientSex ?? string.Empty },
|
||||||
|
|
||||||
{ DicomTag.SeriesInstanceUID, item.SeriesInstanceUid ?? string.Empty },
|
{ DicomTag.StudyInstanceUID, item.StudyInstanceUid ?? string.Empty },
|
||||||
{ DicomTag.Modality, item.Modality ?? string.Empty },
|
{ DicomTag.StudyID, item.StudyId ?? string.Empty },
|
||||||
{ DicomTag.SeriesDate, item.DicomSeriesDate ?? string.Empty },
|
{ DicomTag.StudyDate, item.DicomStudyDate ?? string.Empty },
|
||||||
{ DicomTag.SeriesTime, item.DicomSeriesTime ?? string.Empty },
|
{ DicomTag.StudyTime, item.DicomStudyTime ?? string.Empty },
|
||||||
{ DicomTag.SeriesNumber, item.SeriesNumber.ToString() ?? string.Empty },
|
{ DicomTag.AccessionNumber, item.AccessionNumber ?? string.Empty },
|
||||||
{ DicomTag.SeriesDescription, item.SeriesDescription ?? string.Empty },
|
{ DicomTag.StudyDescription, item.StudyDescription ?? string.Empty },
|
||||||
|
|
||||||
{ DicomTag.SOPInstanceUID, item.SopInstanceUid ?? string.Empty },
|
{ DicomTag.SeriesInstanceUID, item.SeriesInstanceUid ?? string.Empty },
|
||||||
{ DicomTag.SOPClassUID, item.SOPClassUID ?? string.Empty },
|
{ DicomTag.Modality, item.Modality ?? string.Empty },
|
||||||
{ DicomTag.InstanceNumber, item.InstanceNumber.ToString() ?? string.Empty },
|
{ DicomTag.SeriesDate, item.DicomSeriesDate ?? string.Empty },
|
||||||
{ DicomTag.MediaStorageSOPClassUID, item.MediaStorageSOPClassUID ?? string.Empty },
|
{ DicomTag.SeriesTime, item.DicomSeriesTime ?? string.Empty },
|
||||||
{ DicomTag.MediaStorageSOPInstanceUID, item.MediaStorageSOPInstanceUID ?? string.Empty },
|
{ DicomTag.SeriesNumber, item.SeriesNumber.ToString() ?? string.Empty },
|
||||||
{ DicomTag.TransferSyntaxUID, item.TransferSytaxUID ?? string.Empty },
|
{ DicomTag.SeriesDescription, item.SeriesDescription ?? string.Empty },
|
||||||
};
|
|
||||||
|
|
||||||
var dicomFile = new DicomFile(dataset);
|
{ DicomTag.SOPInstanceUID, item.SopInstanceUid ?? string.Empty },
|
||||||
|
{ DicomTag.SOPClassUID, item.SOPClassUID ?? string.Empty },
|
||||||
|
{ DicomTag.InstanceNumber, item.InstanceNumber.ToString() ?? string.Empty },
|
||||||
|
{ DicomTag.MediaStorageSOPClassUID, item.MediaStorageSOPClassUID ?? string.Empty },
|
||||||
|
{ DicomTag.MediaStorageSOPInstanceUID, item.MediaStorageSOPInstanceUID ?? string.Empty },
|
||||||
|
{ DicomTag.TransferSyntaxUID, item.TransferSytaxUID ?? string.Empty },
|
||||||
|
};
|
||||||
|
|
||||||
// 文件名递增格式:IM_00001, IM_00002, ...
|
var dicomFile = new DicomFile(dataset);
|
||||||
string filename = $@"IMAGE/IM_{index:D5}"; // :D5 表示补足5位
|
|
||||||
|
|
||||||
mappings.Add($"{filename} => {item.InstanceId}");
|
// 文件名递增格式:IM_00001, IM_00002, ...
|
||||||
|
string filename = $@"IMAGE/IM_{index:D5}"; // :D5 表示补足5位
|
||||||
|
|
||||||
|
mappings.Add($"{filename} => {item.InstanceId}");
|
||||||
|
|
||||||
|
dic.Add(item.InstanceId.ToString(), filename);
|
||||||
|
|
||||||
|
dicomDir.AddFile(dicomFile, filename);
|
||||||
|
}
|
||||||
|
|
||||||
dic.Add(item.InstanceId.ToString(), filename);
|
|
||||||
|
|
||||||
dicomDir.AddFile(dicomFile, filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region 写入临时路径
|
//有实际的文件
|
||||||
var tempFilePath = Path.GetTempFileName();
|
if (mappings.Count > 0)
|
||||||
|
|
||||||
// 保存 DICOMDIR 到临时文件 不能直接写入到流种
|
|
||||||
await dicomDir.SaveAsync(tempFilePath);
|
|
||||||
|
|
||||||
using (var memoryStream = new MemoryStream(File.ReadAllBytes(tempFilePath)))
|
|
||||||
{
|
{
|
||||||
// 重置流位置
|
#region 写入临时路径
|
||||||
memoryStream.Position = 0;
|
var tempFilePath = Path.GetTempFileName();
|
||||||
|
|
||||||
await _oSSService.UploadToOSSAsync(memoryStream, ossFolder, "DICOMDIR", false);
|
// 保存 DICOMDIR 到临时文件 不能直接写入到流种
|
||||||
|
await dicomDir.SaveAsync(tempFilePath);
|
||||||
|
|
||||||
|
using (var memoryStream = new MemoryStream(File.ReadAllBytes(tempFilePath)))
|
||||||
|
{
|
||||||
|
// 重置流位置
|
||||||
|
memoryStream.Position = 0;
|
||||||
|
|
||||||
|
await _oSSService.UploadToOSSAsync(memoryStream, ossFolder, "DICOMDIR", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//清理临时文件
|
||||||
|
File.Delete(tempFilePath);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 映射上传
|
||||||
|
|
||||||
|
// 将映射写入内存流
|
||||||
|
var mappingText = string.Join(Environment.NewLine, mappings);
|
||||||
|
await using var mappingStream = new MemoryStream(Encoding.UTF8.GetBytes(mappingText));
|
||||||
|
|
||||||
|
await _oSSService.UploadToOSSAsync(mappingStream, ossFolder, $"Download_{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}", false);
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
//清理临时文件
|
|
||||||
File.Delete(tempFilePath);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 映射上传
|
|
||||||
|
|
||||||
// 将映射写入内存流
|
|
||||||
var mappingText = string.Join(Environment.NewLine, mappings);
|
|
||||||
await using var mappingStream = new MemoryStream(Encoding.UTF8.GetBytes(mappingText));
|
|
||||||
|
|
||||||
await _oSSService.UploadToOSSAsync(mappingStream, ossFolder, $"Download_{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}", false);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
return dic;
|
return dic;
|
||||||
}
|
}
|
||||||
|
@ -142,6 +154,7 @@ namespace IRaCIS.Core.Application.Helper
|
||||||
{
|
{
|
||||||
var dataset = dicomFile.Dataset;
|
var dataset = dicomFile.Dataset;
|
||||||
|
|
||||||
|
|
||||||
var info = new StudyDIRInfo
|
var info = new StudyDIRInfo
|
||||||
{
|
{
|
||||||
PatientId = dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty),
|
PatientId = dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty),
|
||||||
|
@ -166,8 +179,10 @@ namespace IRaCIS.Core.Application.Helper
|
||||||
SopInstanceUid = dataset.GetSingleValueOrDefault(DicomTag.SOPInstanceUID, string.Empty),
|
SopInstanceUid = dataset.GetSingleValueOrDefault(DicomTag.SOPInstanceUID, string.Empty),
|
||||||
SOPClassUID = dataset.GetSingleValueOrDefault(DicomTag.SOPClassUID, string.Empty),
|
SOPClassUID = dataset.GetSingleValueOrDefault(DicomTag.SOPClassUID, string.Empty),
|
||||||
InstanceNumber = dataset.GetSingleValueOrDefault(DicomTag.InstanceNumber, 1),
|
InstanceNumber = dataset.GetSingleValueOrDefault(DicomTag.InstanceNumber, 1),
|
||||||
MediaStorageSOPClassUID = dataset.GetSingleValueOrDefault(DicomTag.MediaStorageSOPClassUID, string.Empty),
|
|
||||||
MediaStorageSOPInstanceUID = dataset.GetSingleValueOrDefault(DicomTag.MediaStorageSOPInstanceUID, string.Empty),
|
MediaStorageSOPClassUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.MediaStorageSOPClassUID, string.Empty),
|
||||||
|
MediaStorageSOPInstanceUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.MediaStorageSOPInstanceUID, string.Empty),
|
||||||
|
|
||||||
TransferSytaxUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.TransferSyntaxUID, string.Empty)
|
TransferSytaxUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.TransferSyntaxUID, string.Empty)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
using DocumentFormat.OpenXml.EMMA;
|
using DocumentFormat.OpenXml.EMMA;
|
||||||
using FellowOakDicom;
|
using FellowOakDicom;
|
||||||
|
using FellowOakDicom.Imaging;
|
||||||
|
using FellowOakDicom.Imaging.Render;
|
||||||
|
using FellowOakDicom.IO.Buffer;
|
||||||
using IRaCIS.Core.Application.Helper;
|
using IRaCIS.Core.Application.Helper;
|
||||||
using MassTransit;
|
using MassTransit;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
@ -244,17 +247,86 @@ namespace IRaCIS.Core.Application.Service
|
||||||
[FromServices] IRepository<DicomStudy> _studyRepository,
|
[FromServices] IRepository<DicomStudy> _studyRepository,
|
||||||
[FromServices] IRepository<DicomSeries> _seriesRepository)
|
[FromServices] IRepository<DicomSeries> _seriesRepository)
|
||||||
{
|
{
|
||||||
var list = await _instanceRepository.Where(t => t.TrialId == trialId)
|
var list = await _instanceRepository.Where(t => t.TrialId == trialId && t.SubjectVisitId == Guid.Parse("01000000-0a00-0242-bd20-08dcce543ded"))
|
||||||
.Select(t => new { t.SeriesId, t.StudyId, t.Id, t.Path }).ToListAsync();
|
.Select(t => new { t.SeriesId, t.StudyId, t.Id, t.Path }).ToListAsync();
|
||||||
|
|
||||||
|
int totalCount = list.Count;
|
||||||
|
int dealCount = 0;
|
||||||
foreach (var item in list)
|
foreach (var item in list)
|
||||||
{
|
{
|
||||||
|
dealCount++;
|
||||||
|
|
||||||
var stream = await _oSSService.GetStreamFromOSSAsync(item.Path);
|
var stream = await _oSSService.GetStreamFromOSSAsync(item.Path);
|
||||||
|
|
||||||
var dicomFile = DicomFile.Open(stream);
|
var dicomFile = DicomFile.Open(stream);
|
||||||
|
|
||||||
|
// 获取 Pixel Data 标签
|
||||||
|
var pixelData = DicomPixelData.Create(dicomFile.Dataset);
|
||||||
|
|
||||||
|
//获取像素是否为封装形式
|
||||||
|
var syntax = dicomFile.Dataset.InternalTransferSyntax;
|
||||||
|
|
||||||
|
//对于封装像素的文件做转换
|
||||||
|
if (syntax.IsEncapsulated)
|
||||||
|
{
|
||||||
|
// 创建一个新的片段序列
|
||||||
|
var newFragments = new DicomOtherByteFragment(DicomTag.PixelData);
|
||||||
|
// 获取每帧数据并封装为单独的片段
|
||||||
|
for (int n = 0; n < pixelData.NumberOfFrames; n++)
|
||||||
|
{
|
||||||
|
var frameData = pixelData.GetFrame(n);
|
||||||
|
newFragments.Fragments.Add(new MemoryByteBuffer(frameData.Data));
|
||||||
|
}
|
||||||
|
// 替换原有的片段序列
|
||||||
|
dicomFile.Dataset.AddOrUpdate(newFragments);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region 获取dir信息 维护数据库三个表数据
|
||||||
|
|
||||||
var dirInfo = DicomDIRHelper.ReadDicomDIRInfo(dicomFile);
|
var dirInfo = DicomDIRHelper.ReadDicomDIRInfo(dicomFile);
|
||||||
|
|
||||||
|
await _instanceRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id,
|
||||||
|
u => new DicomInstance()
|
||||||
|
{
|
||||||
|
TransferSytaxUID = dirInfo.TransferSytaxUID,
|
||||||
|
SOPClassUID = dirInfo.SOPClassUID,
|
||||||
|
MediaStorageSOPClassUID = dirInfo.MediaStorageSOPClassUID,
|
||||||
|
MediaStorageSOPInstanceUID = dirInfo.MediaStorageSOPInstanceUID
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
await _seriesRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.SeriesId,
|
||||||
|
u => new DicomSeries()
|
||||||
|
{
|
||||||
|
DicomSeriesDate = dirInfo.DicomSeriesDate,
|
||||||
|
DicomSeriesTime = dirInfo.DicomSeriesTime,
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
await _studyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.StudyId,
|
||||||
|
u => new DicomStudy()
|
||||||
|
{
|
||||||
|
DicomStudyDate = dirInfo.DicomStudyDate,
|
||||||
|
DicomStudyTime = dirInfo.DicomStudyTime
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//保存到内存流
|
||||||
|
using var memoryStream = new MemoryStream();
|
||||||
|
dicomFile.Save(memoryStream);
|
||||||
|
memoryStream.Position = 0;
|
||||||
|
|
||||||
|
//获取原始目录 和文件名
|
||||||
|
var folder = item.Path.Substring(0, item.Path.LastIndexOf('/')).TrimStart('/');
|
||||||
|
var fileName = Path.GetFileName(item.Path);
|
||||||
|
|
||||||
|
await _oSSService.UploadToOSSAsync(memoryStream, folder, fileName, false);
|
||||||
|
|
||||||
|
dealCount++;
|
||||||
|
|
||||||
|
Console.WriteLine($"{DateTime.Now}已下载 {dealCount} / {totalCount} 个文件,完成 {(dealCount * 100.0 / totalCount):F2}%");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResponseOutput.Ok();
|
return ResponseOutput.Ok();
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
|
using FellowOakDicom;
|
||||||
|
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
@ -330,6 +331,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||||
public List<AddOrUpdateSeriesDto> SeriesList { get; set; }
|
public List<AddOrUpdateSeriesDto> SeriesList { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AddOrUpdateSeriesDto
|
public class AddOrUpdateSeriesDto
|
||||||
|
@ -402,7 +404,10 @@ namespace IRaCIS.Core.Application.Contracts
|
||||||
|
|
||||||
public string TransferSytaxUID { get; set; }
|
public string TransferSytaxUID { get; set; }
|
||||||
|
|
||||||
public string mediaStorageSOPInstanceUID { get; set; }
|
public string MediaStorageSOPInstanceUID { get; set; }
|
||||||
|
|
||||||
|
public bool IsEncapsulated => DicomTransferSyntax.Lookup(DicomUID.Parse(TransferSytaxUID)).IsEncapsulated;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CRCUploadTaskQuery
|
public class CRCUploadTaskQuery
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class DicomInstance : BaseFullDeleteAuditEntity, IEntitySeqId
|
||||||
|
|
||||||
public int ImageRows { get; set; }
|
public int ImageRows { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public string ImagerPixelSpacing { get; set; } = null!;
|
public string ImagerPixelSpacing { get; set; } = null!;
|
||||||
|
|
||||||
public int InstanceNumber { get; set; }
|
public int InstanceNumber { get; set; }
|
||||||
|
@ -44,7 +44,7 @@ public class DicomInstance : BaseFullDeleteAuditEntity, IEntitySeqId
|
||||||
[StringLength(1000)]
|
[StringLength(1000)]
|
||||||
public string Path { get; set; } = null!;
|
public string Path { get; set; } = null!;
|
||||||
|
|
||||||
|
|
||||||
public string PixelSpacing { get; set; } = null!;
|
public string PixelSpacing { get; set; } = null!;
|
||||||
|
|
||||||
public Guid SeqId { get; set; }
|
public Guid SeqId { get; set; }
|
||||||
|
@ -55,7 +55,7 @@ public class DicomInstance : BaseFullDeleteAuditEntity, IEntitySeqId
|
||||||
|
|
||||||
public int SliceLocation { get; set; }
|
public int SliceLocation { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public string SliceThickness { get; set; } = null!;
|
public string SliceThickness { get; set; } = null!;
|
||||||
|
|
||||||
public string SopInstanceUid { get; set; } = null!;
|
public string SopInstanceUid { get; set; } = null!;
|
||||||
|
@ -70,10 +70,10 @@ public class DicomInstance : BaseFullDeleteAuditEntity, IEntitySeqId
|
||||||
|
|
||||||
public Guid TrialId { get; set; }
|
public Guid TrialId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public string WindowCenter { get; set; } = null!;
|
public string WindowCenter { get; set; } = null!;
|
||||||
|
|
||||||
|
|
||||||
public string WindowWidth { get; set; } = null!;
|
public string WindowWidth { get; set; } = null!;
|
||||||
|
|
||||||
public bool IsReading { get; set; } = true;
|
public bool IsReading { get; set; } = true;
|
||||||
|
@ -90,5 +90,7 @@ public class DicomInstance : BaseFullDeleteAuditEntity, IEntitySeqId
|
||||||
|
|
||||||
public string MediaStorageSOPInstanceUID { get; set; }
|
public string MediaStorageSOPInstanceUID { get; set; }
|
||||||
|
|
||||||
|
public bool IsEncapsulated { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
19963
IRaCIS.Core.Infra.EFCore/Migrations/20250808062746_addIsEncapsulated.Designer.cs
generated
Normal file
19963
IRaCIS.Core.Infra.EFCore/Migrations/20250808062746_addIsEncapsulated.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,29 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Infra.EFCore.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class addIsEncapsulated : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "IsEncapsulated",
|
||||||
|
table: "DicomInstance",
|
||||||
|
type: "bit",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "IsEncapsulated",
|
||||||
|
table: "DicomInstance");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -930,6 +930,9 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
||||||
b.Property<bool>("IsDeleted")
|
b.Property<bool>("IsDeleted")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
b.Property<bool>("IsEncapsulated")
|
||||||
|
.HasColumnType("bit");
|
||||||
|
|
||||||
b.Property<bool>("IsReading")
|
b.Property<bool>("IsReading")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace IRaCIS.Core.Infra.EFCore
|
||||||
Task<bool> BatchDeleteNoTrackingAsync(Expression<Func<TEntity, bool>> deleteFilter);
|
Task<bool> BatchDeleteNoTrackingAsync(Expression<Func<TEntity, bool>> deleteFilter);
|
||||||
|
|
||||||
/// <summary>批量更新,相当于原生sql, 没用EF跟踪方式(所有查询出来,再更新 浪费性能)</summary>
|
/// <summary>批量更新,相当于原生sql, 没用EF跟踪方式(所有查询出来,再更新 浪费性能)</summary>
|
||||||
Task<bool> BatchUpdateNoTrackingAsync(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, TEntity>> updateFactory);
|
Task<bool> BatchUpdateNoTrackingAsync(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, TEntity>> updateFactory, bool isAutoIncludeTimeAndUser = true);
|
||||||
|
|
||||||
Task<bool> ExecuteUpdateAsync(Expression<Func<TEntity, bool>> where, Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setPropertyCalls);
|
Task<bool> ExecuteUpdateAsync(Expression<Func<TEntity, bool>> where, Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setPropertyCalls);
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ namespace IRaCIS.Core.Infra.EFCore
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
void MarkAsModified<TFrom>(TFrom entity, string propertyName);
|
void MarkAsModified<TFrom>(TFrom entity, string propertyName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,7 @@ namespace IRaCIS.Core.Infra.EFCore
|
||||||
|
|
||||||
|
|
||||||
/// <summary>批量更新,相当于原生sql, 没用EF跟踪方式(所有查询出来,再更新 浪费性能)</summary>
|
/// <summary>批量更新,相当于原生sql, 没用EF跟踪方式(所有查询出来,再更新 浪费性能)</summary>
|
||||||
public static async Task<bool> BatchUpdateNoTrackingAsync<T>(this IRaCISDBContext _dbContext, Expression<Func<T, bool>> where, Expression<Func<T, T>> updateFactory, Guid updateUserId) where T : Entity
|
public static async Task<bool> BatchUpdateNoTrackingAsync<T>(this IRaCISDBContext _dbContext, Expression<Func<T, bool>> where, Expression<Func<T, T>> updateFactory, Guid updateUserId, bool isAutoIncludeTimeAndUser = true) where T : Entity
|
||||||
{
|
{
|
||||||
if (where == null) throw new ArgumentNullException(nameof(where));
|
if (where == null) throw new ArgumentNullException(nameof(where));
|
||||||
|
|
||||||
|
@ -202,15 +202,17 @@ namespace IRaCIS.Core.Infra.EFCore
|
||||||
|
|
||||||
if (typeof(IAuditUpdate).IsAssignableFrom(typeof(T)))
|
if (typeof(IAuditUpdate).IsAssignableFrom(typeof(T)))
|
||||||
{
|
{
|
||||||
|
if (isAutoIncludeTimeAndUser)
|
||||||
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateTime)))
|
|
||||||
{
|
{
|
||||||
fieldValues.Add(nameof(IAuditUpdate.UpdateTime), DateTime.Now);
|
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateTime)))
|
||||||
}
|
{
|
||||||
|
fieldValues.Add(nameof(IAuditUpdate.UpdateTime), DateTime.Now);
|
||||||
|
}
|
||||||
|
|
||||||
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateUserId)))
|
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateUserId)))
|
||||||
{
|
{
|
||||||
fieldValues.Add(nameof(IAuditUpdate.UpdateUserId), updateUserId);
|
fieldValues.Add(nameof(IAuditUpdate.UpdateUserId), updateUserId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -297,10 +297,10 @@ namespace IRaCIS.Core.Infra.EFCore
|
||||||
|
|
||||||
/// <summary>批量更新,相当于原生sql, 没用EF跟踪方式(所有查询出来,再更新 浪费性能)</summary>
|
/// <summary>批量更新,相当于原生sql, 没用EF跟踪方式(所有查询出来,再更新 浪费性能)</summary>
|
||||||
public async Task<bool> BatchUpdateNoTrackingAsync(Expression<Func<TEntity, bool>> where,
|
public async Task<bool> BatchUpdateNoTrackingAsync(Expression<Func<TEntity, bool>> where,
|
||||||
Expression<Func<TEntity, TEntity>> updateFactory)
|
Expression<Func<TEntity, TEntity>> updateFactory ,bool isAutoIncludeTimeAndUser = true)
|
||||||
{
|
{
|
||||||
|
|
||||||
return await _dbContext.BatchUpdateNoTrackingAsync(where, updateFactory, _userInfo.UserRoleId);
|
return await _dbContext.BatchUpdateNoTrackingAsync(where, updateFactory, _userInfo.UserRoleId, isAutoIncludeTimeAndUser);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue