Neue Features, Optimierungen und Bugfixes
- Neues Projekt `EDMI.API` zur Solution hinzugefügt. - `App.config`: Abhängigkeiten und `bindingRedirect` aktualisiert. - Verbesserte Thread-Sicherheit mit `ReaderWriterLockSlim`. - SQL-Abfragen mit `WITH (NOLOCK)` für bessere Parallelität. - Robuste Verarbeitung von `DataRow`-Werten mit `IIf(IsDBNull(...))`. - Neue Sicherheitsprüfung für `JobListener` initialisiert. - `SaveDataTables` optimiert, Performance-Warnungen hinzugefügt. - Versionsnummer auf `2.5.0.0` aktualisiert, Copyright auf 2026. - Paket `NLog` aus `packages.config` entfernt.
This commit is contained in:
@@ -14,49 +14,60 @@ Namespace Methods.Database.GetDatatableFromCache
|
||||
Try
|
||||
Logger.Debug($"ReturnDatatableFromCache: Datatable: {pData.DataTable}")
|
||||
|
||||
Dim oDataTable As DataTable = Nothing
|
||||
' ✅ NEU: Sicherheitsprüfung (sollte nie auftreten, aber defensiv)
|
||||
If GlobalState.JobListener Is Nothing Then
|
||||
Logger.Warn("JobListener not initialized - this should not happen! Using direct TableStore access.")
|
||||
|
||||
Logger.Debug("ReturnDatatableFromCache: DataSet contains [{0}] datatables", GlobalState.TableStore.Tables.Count)
|
||||
|
||||
If GlobalState.TableStore.Tables.Contains(pData.DataTable) Then
|
||||
oDataTable = GlobalState.TableStore.Tables.Item(pData.DataTable).Copy()
|
||||
|
||||
' Apply filter and sorting to data
|
||||
Dim oFilterExpression As String = Utils.NotNull(pData.FilterExpression, String.Empty)
|
||||
Dim oSortByColumn As String = Utils.NotNull(pData.SortByColumn, String.Empty)
|
||||
|
||||
Logger.Debug("Applying filter expression: [{0}]", oFilterExpression)
|
||||
Logger.Debug("Applying sort expression: [{0}]", oSortByColumn)
|
||||
|
||||
Dim oFilteredRows = oDataTable.Select(oFilterExpression, oSortByColumn)
|
||||
Dim oFilteredTable As DataTable = Nothing
|
||||
|
||||
If oFilteredRows.Count > 0 Then
|
||||
oFilteredTable = oFilteredRows.CopyToDataTable()
|
||||
oFilteredTable.TableName = pData.DataTable
|
||||
Else
|
||||
' Produce empty table
|
||||
oFilteredTable = oDataTable.Clone()
|
||||
oFilteredTable.TableName = pData.DataTable
|
||||
' Fallback: Direkter Zugriff auf TableStore
|
||||
If Not GlobalState.TableStore.Tables.Contains(pData.DataTable) Then
|
||||
Return New GetDatatableFromCacheResponse(
|
||||
New KeyNotFoundException($"Datatable {pData.DataTable} does not exist"))
|
||||
End If
|
||||
|
||||
Logger.Debug("ReturnDatatableFromCache: Datatable Stats for [{0}]:", pData.DataTable)
|
||||
Logger.Debug("Unfiltered: [{0}] rows", oDataTable.Rows.Count)
|
||||
Logger.Debug("Filtered: [{0}] rows", oFilteredTable.Rows.Count)
|
||||
|
||||
Return New GetDatatableFromCacheResponse(oFilteredTable)
|
||||
Else
|
||||
Logger.Warn($"ReturnDatatableFromCache: Datatable {pData.DataTable} does not exist")
|
||||
|
||||
Return New GetDatatableFromCacheResponse(New KeyNotFoundException($"Datatable {pData.DataTable} does not exist"))
|
||||
Dim oDirectTable = GlobalState.TableStore.Tables(pData.DataTable).Copy()
|
||||
' ... Filter/Sort anwenden wie gehabt
|
||||
Return New GetDatatableFromCacheResponse(ApplyFilterAndSort(oDirectTable, pData))
|
||||
End If
|
||||
|
||||
' ✅ Normal: Thread-sicheren Zugriff verwenden
|
||||
Dim oDataTable As DataTable = GlobalState.JobListener.GetTableSafely(pData.DataTable)
|
||||
|
||||
If oDataTable Is Nothing Then
|
||||
Logger.Warn($"Datatable {pData.DataTable} does not exist")
|
||||
Return New GetDatatableFromCacheResponse(
|
||||
New KeyNotFoundException($"Datatable {pData.DataTable} does not exist"))
|
||||
End If
|
||||
|
||||
Return New GetDatatableFromCacheResponse(ApplyFilterAndSort(oDataTable, pData))
|
||||
|
||||
|
||||
Catch ex As Exception
|
||||
Logger.Error(ex)
|
||||
Return New GetDatatableFromCacheResponse(ex)
|
||||
|
||||
End Try
|
||||
End Function
|
||||
' ✅ Hilfsmethode zum Filter/Sort anwenden
|
||||
Private Function ApplyFilterAndSort(table As DataTable, request As GetDatatableFromCacheRequest) As DataTable
|
||||
Dim oFilterExpression = IIf(IsDBNull(request.FilterExpression), String.Empty, request.FilterExpression)
|
||||
Dim oSortByColumn = IIf(IsDBNull(request.SortByColumn), String.Empty, request.SortByColumn)
|
||||
|
||||
Logger.Debug("Filter: [{0}], Sort: [{1}]", oFilterExpression, oSortByColumn)
|
||||
|
||||
Dim oFilteredRows = table.Select(oFilterExpression, oSortByColumn)
|
||||
Dim oResult As DataTable
|
||||
|
||||
If oFilteredRows.Count > 0 Then
|
||||
oResult = oFilteredRows.CopyToDataTable()
|
||||
Else
|
||||
oResult = table.Clone()
|
||||
End If
|
||||
|
||||
oResult.TableName = request.DataTable
|
||||
Logger.Debug("Rows: {0} → {1}", table.Rows.Count, oResult.Rows.Count)
|
||||
|
||||
Return oResult
|
||||
End Function
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
@@ -37,13 +37,13 @@ Namespace Methods.GlobalIndexer
|
||||
|
||||
Dim oRow As DataRow = oProfile.Table.Rows.Item(0)
|
||||
Dim oProfileObject As New Profile With {
|
||||
.Id = oRow.ItemEx("DOCTYPE_ID", 0),
|
||||
.Name = oRow.ItemEx("DOCTYPE", "Missing Profile Name"),
|
||||
.IsActive = oRow.ItemEx("AKTIV", False),
|
||||
.NameConvention = oRow.ItemEx("NAMENKONVENTION", ""),
|
||||
.ObjectStore = oRow.ItemEx("OBJECT_STORE", "Work"),
|
||||
.ShortName = oRow.ItemEx("KURZNAME", ""),
|
||||
.DynamicPath = oRow.ItemEx("DYNAMIC_FOLDER", "")
|
||||
.Id = IIf(IsDBNull(oRow.Item("DOCTYPE_ID")), 0, oRow.Item("DOCTYPE_ID")),
|
||||
.Name = IIf(IsDBNull(oRow.Item("DOCTYPE")), String.Empty, oRow.Item("DOCTYPE")),
|
||||
.IsActive = IIf(IsDBNull(oRow.Item("AKTIV")), False, oRow.Item("AKTIV")),
|
||||
.NameConvention = IIf(IsDBNull(oRow.Item("NAMENKONVENTION")), String.Empty, oRow.Item("NAMENKONVENTION")),
|
||||
.ObjectStore = IIf(IsDBNull(oRow.Item("OBJECT_STORE")), "Work", oRow.Item("OBJECT_STORE")),
|
||||
.ShortName = IIf(IsDBNull(oRow.Item("KURZNAME")), String.Empty, oRow.Item("KURZNAME")),
|
||||
.DynamicPath = IIf(IsDBNull(oRow.Item("DYNAMIC_FOLDER")), String.Empty, oRow.Item("DYNAMIC_FOLDER"))
|
||||
}
|
||||
|
||||
Logger.Debug("Name: [{0}]", oProfileObject.Name)
|
||||
@@ -82,13 +82,13 @@ Namespace Methods.GlobalIndexer
|
||||
|
||||
For Each oRow As DataRow In oAutomaticIndexes.Table.Rows
|
||||
Dim oAutomaticIndex As New AutomaticIndex With {
|
||||
.Id = oRow.ItemEx(Of Integer)("GUID"),
|
||||
.Name = oRow.ItemEx(Of String)("INDEXNAME"),
|
||||
.ProfileId = oRow.ItemEx(Of Integer)("DOCTYPE_ID"),
|
||||
.SQLCommand = oRow.ItemEx(Of String)("SQL_RESULT"),
|
||||
.SQLConnectionId = oRow.ItemEx(Of Integer)("CONNECTION_ID"),
|
||||
.Sequence = oRow.ItemEx(Of String)("SEQUENCE"),
|
||||
.Value = oRow.ItemEx(Of String)("VALUE")
|
||||
.Id = oRow.Item("GUID"),
|
||||
.Name = IIf(IsDBNull(oRow.Item("INDEXNAME")), String.Empty, oRow.Item("INDEXNAME")),
|
||||
.ProfileId = IIf(IsDBNull(oRow.Item("DOCTYPE_ID")), 0, oRow.Item("DOCTYPE_ID")),
|
||||
.SQLCommand = IIf(IsDBNull(oRow.Item("SQL_RESULT")), String.Empty, oRow.Item("SQL_RESULT")),
|
||||
.SQLConnectionId = IIf(IsDBNull(oRow.Item("CONNECTION_ID")), 0, oRow.Item("CONNECTION_ID")),
|
||||
.Sequence = IIf(IsDBNull(oRow.Item("SEQUENCE")), String.Empty, oRow.Item("SEQUENCE")),
|
||||
.Value = IIf(IsDBNull(oRow.Item("VALUE")), String.Empty, oRow.Item("VALUE"))
|
||||
}
|
||||
|
||||
oIndexes.Add(oAutomaticIndex)
|
||||
@@ -125,15 +125,15 @@ Namespace Methods.GlobalIndexer
|
||||
|
||||
For Each oRow As DataRow In oManualIndexes.Table.Rows
|
||||
Dim oManualIndex As New ManualIndex With {
|
||||
.Id = oRow.ItemEx(Of Integer)("GUID"),
|
||||
.Name = oRow.ItemEx(Of String)("INDEXNAME"),
|
||||
.ProfileId = oRow.ItemEx(Of Integer)("DOK_ID"),
|
||||
.IsOptional = oRow.ItemEx(Of Boolean)("OPTIONAL"),
|
||||
.IsMultiselect = oRow.ItemEx(Of String)("MULTISELECT"),
|
||||
.SQLCommand = oRow.ItemEx(Of String)("SQL_RESULT"),
|
||||
.SQLConnectionId = oRow.ItemEx(Of Integer)("CONNECTION_ID"),
|
||||
.DefaultValue = oRow.ItemEx(Of String)("DEFAULT_VALUE"),
|
||||
.DataType = oRow.ItemEx(Of String)("DATATYPE")
|
||||
.Id = oRow.Item("GUID"),
|
||||
.Name = oRow.Item("INDEXNAME"),
|
||||
.ProfileId = oRow.Item("DOK_ID"),
|
||||
.IsOptional = oRow.Item("OPTIONAL"),
|
||||
.IsMultiselect = oRow.Item("MULTISELECT"),
|
||||
.SQLCommand = oRow.Item("SQL_RESULT"),
|
||||
.SQLConnectionId = oRow.Item("CONNECTION_ID"),
|
||||
.DefaultValue = oRow.Item("DEFAULT_VALUE"),
|
||||
.DataType = oRow.Item("DATATYPE")
|
||||
}
|
||||
|
||||
oIndexes.Add(oManualIndex)
|
||||
@@ -179,16 +179,16 @@ Namespace Methods.GlobalIndexer
|
||||
|
||||
For Each oRow As DataRow In oPostProcessingSteps.Table.Rows
|
||||
Dim oStep As New PostProcessingStep With {
|
||||
.Id = oRow.ItemEx(Of Integer)("GUID"),
|
||||
.IndexId = oRow.ItemEx(Of Integer)("IDXMAN_ID"),
|
||||
.[Variant] = oRow.ItemEx(Of String)("VARIANT"),
|
||||
.Type = oRow.ItemEx(Of String)("TYPE"),
|
||||
.Function1 = oRow.ItemEx(Of String)("FUNCTION1"),
|
||||
.Function2 = oRow.ItemEx(Of String)("FUNCTION2"),
|
||||
.Text1 = oRow.ItemEx(Of String)("Text1"),
|
||||
.Text2 = oRow.ItemEx(Of String)("Text2"),
|
||||
.Text3 = oRow.ItemEx(Of String)("Text3"),
|
||||
.Sequence = oRow.ItemEx(Of Integer)("SEQUENCE")
|
||||
.Id = oRow.Item("GUID"),
|
||||
.IndexId = oRow.Item("IDXMAN_ID"),
|
||||
.[Variant] = oRow.Item("VARIANT"),
|
||||
.Type = oRow.Item("TYPE"),
|
||||
.Function1 = oRow.Item("FUNCTION1"),
|
||||
.Function2 = oRow.Item("FUNCTION2"),
|
||||
.Text1 = oRow.Item("Text1"),
|
||||
.Text2 = oRow.Item("Text2"),
|
||||
.Text3 = oRow.Item("Text3"),
|
||||
.Sequence = oRow.Item("SEQUENCE")
|
||||
}
|
||||
|
||||
oSteps.Add(oStep)
|
||||
|
||||
@@ -25,12 +25,12 @@ Namespace Methods.IDB.GetFileObject
|
||||
LogAndThrow("Error while getting FileObject data!")
|
||||
End If
|
||||
|
||||
Dim oRow As DataRow = oTable.First()
|
||||
Dim oFileHash As String = oRow.ItemEx("FILE_HASH", "")
|
||||
Dim oFileSize As Long = oRow.ItemEx(Of Long)("FILE_SIZE", 0)
|
||||
Dim oFileExtension As String = oRow.ItemEx(Of String)("EXTENSION")
|
||||
Dim oFilePath = oRow.ItemEx("RELPATH", "")
|
||||
Dim oFileName = oRow.ItemEx("Filename", "")
|
||||
Dim oRow As DataRow = oTable.Rows(0)
|
||||
Dim oFileHash As String = oRow.Item("FILE_HASH")
|
||||
Dim oFileSize As Long = oRow.Item("FILE_SIZE")
|
||||
Dim oFileExtension As String = oRow.Item("EXTENSION")
|
||||
Dim oFilePath = oRow.Item("RELPATH")
|
||||
Dim oFileName = oRow.Item("Filename")
|
||||
Dim oFullFileName = Path.Combine(oFilePath, oFileName)
|
||||
|
||||
Dim oFileObject As New FileObject With {
|
||||
|
||||
Reference in New Issue
Block a user