diff --git a/ENI2/DetailRootControl.xaml.cs b/ENI2/DetailRootControl.xaml.cs index 71480c7b..1d11a210 100644 --- a/ENI2/DetailRootControl.xaml.cs +++ b/ENI2/DetailRootControl.xaml.cs @@ -333,7 +333,7 @@ namespace ENI2 // Bearbeitungsinformationen für bestehende ID-Beantragung beibehalten, falls bereits vorhanden - if(existingCore.IsTransit && + if(existingCore.IsTransit && (existingMessage.MessageNotificationClass == Message.NotificationClass.TRANSIT) && (existingMessage.InternalStatus == Message.BSMDStatus.CONFIRMED)) { @@ -392,7 +392,7 @@ namespace ENI2 newMessage.MessageCoreId = newCore.Id; DBManager.GetSingleCon(Properties.Settings.Default.ConnectionString).Save(newMessage); newMessage.SaveElements(); - } + } this.OnOpenNewCoreRequested(newCore); } diff --git a/bsmd.database/CREW.cs b/bsmd.database/CREW.cs index bbc1f5de..59f0c610 100644 --- a/bsmd.database/CREW.cs +++ b/bsmd.database/CREW.cs @@ -14,7 +14,7 @@ using System.Collections.Generic; namespace bsmd.database { - public class CREW : DatabaseEntity, ISublistElement + public class CREW : DatabaseEntity, ISublistElement, IBulkSaver { public CREW() @@ -272,6 +272,62 @@ namespace bsmd.database #endregion + #region IBulkSaver implementation + + public DataTable PrepareBulkInsert(List databaseEntities) + { + DataTable result = new DataTable(); + + result.Columns.Add(new DataColumn { ColumnName = "MessageHeaderId", DataType = MessageHeader.Id.GetType() }); + result.Columns.Add(new DataColumn { ColumnName = "CrewMemberLastName", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "CrewMemberFirstName", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "CrewMemberPlaceOfBirth", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "CrewMemberDateOfBirth", DataType = typeof(DateTime), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "CrewMemberGender", DataType = typeof(byte), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "CrewMemberNationality", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "CrewMemberIdentityDocumentType", DataType = typeof(byte), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "CrewMemberIdentityDocumentId", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "CrewMemberVisaNumber", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "CrewMemberDuty", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "Identifier", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "IsDeparture", DataType = typeof(bool), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "CrewMemberIdentityDocumentIssuingState", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "CrewMemberIdentityDocumentExpiryDate", DataType = typeof(DateTime), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "NotificationSchengen", DataType = typeof(bool), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "NotificationPAX", DataType = typeof(bool), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "CrewMemberCountryOfBirth", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "Effects", DataType = typeof(string), AllowDBNull = true }); + + foreach (CREW crew in databaseEntities) + { + DataRow row = result.NewRow(); + row[0] = crew.MessageHeader.Id; + row[1] = crew.CrewMemberLastName ?? (object)DBNull.Value; + row[2] = crew.CrewMemberFirstName ?? (object)DBNull.Value; + row[3] = crew.CrewMemberPlaceOfBirth ?? (object)DBNull.Value; + row[4] = crew.CrewMemberDateOfBirth ?? (object)DBNull.Value; + row[5] = crew.CrewMemberGender ?? (object)DBNull.Value; + row[6] = crew.CrewMemberNationality ?? (object)DBNull.Value; + row[7] = crew.CrewMemberIdentityDocumentType ?? (object)DBNull.Value; + row[8] = crew.CrewMemberIdentityDocumentId ?? (object)DBNull.Value; + row[9] = crew.CrewMemberVisaNumber ?? (object)DBNull.Value; + row[10] = crew.CrewMemberDuty ?? (object)DBNull.Value; + row[11] = crew.Identifier ?? (object)DBNull.Value; + row[12] = crew.IsDeparture; + row[13] = crew.CrewMemberIdentityDocumentIssuingState ?? (object)DBNull.Value; + row[14] = crew.CrewMemberIdentityDocumentExpiryDate ?? (object)DBNull.Value; + row[15] = crew.NotificationSchengen ?? (object)DBNull.Value; + row[16] = crew.NotificationPAX ?? (object)DBNull.Value; + row[17] = crew.CrewMemberCountryOfBirth ?? (object)DBNull.Value; + row[18] = crew.Effects ?? (object)DBNull.Value; + result.Rows.Add(row); + } + + return result; + } + + #endregion + } #region CREWD diff --git a/bsmd.database/ISublistContainer.cs b/bsmd.database/ISublistContainer.cs index f4e19172..7dd0ff4c 100644 --- a/bsmd.database/ISublistContainer.cs +++ b/bsmd.database/ISublistContainer.cs @@ -1,8 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Data; namespace bsmd.database { @@ -50,4 +47,9 @@ namespace bsmd.database string Identifier { get; set; } } + public interface IBulkSaver + { + DataTable PrepareBulkInsert(List databaseEntities); + } + } diff --git a/bsmd.database/ImportValue.cs b/bsmd.database/ImportValue.cs index d6baab5d..523e5890 100644 --- a/bsmd.database/ImportValue.cs +++ b/bsmd.database/ImportValue.cs @@ -125,7 +125,7 @@ namespace bsmd.database // create table columns foreach (PropertyInfo p in properties) { - if (!(p.CanRead && p.CanWrite)) continue; + if (!(p.CanRead && p.CanWrite)) continue; Type propType = p.PropertyType; DataColumn dc = new DataColumn(); dc.ColumnName = p.Name; diff --git a/bsmd.database/Message.cs b/bsmd.database/Message.cs index 26b2d1a9..d5af0c91 100644 --- a/bsmd.database/Message.cs +++ b/bsmd.database/Message.cs @@ -692,12 +692,19 @@ namespace bsmd.database public void SaveElements() { - foreach (DatabaseEntity dbEntity in this.Elements) - { - DBManager.Instance.Save(dbEntity); - if (dbEntity is ISublistContainer sublistContainer) + if (CanDoBulkSave()) + { + this.BulkSaveElements(); + } + else + { + foreach (DatabaseEntity dbEntity in this.Elements) { - (sublistContainer).SaveElements(); + DBManager.Instance.Save(dbEntity); + if (dbEntity is ISublistContainer sublistContainer) + { + sublistContainer.SaveElements(); + } } } } @@ -857,7 +864,7 @@ namespace bsmd.database } #endregion - + #region IComparable implementation /// @@ -903,6 +910,39 @@ namespace bsmd.database else this.Flags &= (int)~flag; } + /// + /// Bulk save is actually bulk insert and can only be done for certain + /// message classes where bulk save is implemented + /// + private bool CanDoBulkSave() + { + if(this.MessageNotificationClass == NotificationClass.CREW || + this.MessageNotificationClass == NotificationClass.CREWD || + this.MessageNotificationClass == NotificationClass.PAS || + this.MessageNotificationClass == NotificationClass.PASD) + { + foreach (DatabaseEntity subEntity in this.Elements) + if (!subEntity.IsNew) + return false; + return true; + } + return false; + } + + private void BulkSaveElements() + { + if (this.Elements.Count == 0) return; // NOP + if(this.Elements[0] is IBulkSaver ibs) + { + DataTable dt = ibs.PrepareBulkInsert(new List(this.Elements)); + DBManager.Instance.PerformBulkInsert(dt); + } + else + { + throw new InvalidOperationException("bulk save called on classes that do not support it"); + } + } + #endregion } } diff --git a/bsmd.database/PAS.cs b/bsmd.database/PAS.cs index aeaaa61c..bb4523aa 100644 --- a/bsmd.database/PAS.cs +++ b/bsmd.database/PAS.cs @@ -14,7 +14,7 @@ using System.Collections.Generic; namespace bsmd.database { - public class PAS : DatabaseEntity, ISublistElement + public class PAS : DatabaseEntity, ISublistElement, IBulkSaver { public PAS() @@ -331,6 +331,70 @@ namespace bsmd.database #endregion + #region IBulkSaver implementation + + public DataTable PrepareBulkInsert(List databaseEntities) + { + DataTable result = new DataTable(); + + result.Columns.Add(new DataColumn { ColumnName = "MessageHeaderId", DataType = MessageHeader.Id.GetType() }); + result.Columns.Add(new DataColumn { ColumnName = "PassengerLastName", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "PassengerFirstName", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "PassengerPlaceOfBirth", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "PassengerDateOfBirth", DataType = typeof(DateTime), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "PassengerGender", DataType = typeof(byte), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "PassengerNationality", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "PassengerIdentityDocumentType", DataType = typeof(byte), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "PassengerIdentityDocumentId", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "PassengerVisaNumber", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "PassengerPortOfEmbarkation", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "PassengerPortOfDisembarkation", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "PassengerInTransit", DataType = typeof(bool), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "Identifier", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "IsDeparture", DataType = typeof(bool), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "PassengerIdentityDocumentIssuingState", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "PassengerIdentityDocumentExpiryDate", DataType = typeof(DateTime), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "NotificationSchengen", DataType = typeof(bool), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "NotificationPAX", DataType = typeof(bool), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "EmergencyCare", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "EmergencyContactNumber", DataType = typeof(string), AllowDBNull = true }); + result.Columns.Add(new DataColumn { ColumnName = "PassengerCountryOfBirth", DataType = typeof(string), AllowDBNull = true }); + + foreach (PAS pas in databaseEntities) + { + DataRow row = result.NewRow(); + + row[0] = pas.MessageHeader.Id; + row[1] = pas.PassengerLastName ?? (object)DBNull.Value; + row[2] = pas.PassengerFirstName ?? (object)DBNull.Value; + row[3] = pas.PassengerPlaceOfBirth ?? (object)DBNull.Value; + row[4] = pas.PassengerDateOfBirth ?? (object)DBNull.Value; + row[5] = pas.PassengerGender ?? (object)DBNull.Value; + row[6] = pas.PassengerNationality ?? (object)DBNull.Value; + row[7] = pas.PassengerIdentityDocumentType ?? (object)DBNull.Value; + row[8] = pas.PassengerIdentityDocumentId ?? (object)DBNull.Value; + row[9] = pas.PassengerVisaNumber ?? (object)DBNull.Value; + row[10] = pas.PassengerPortOfEmbarkation ?? (object)DBNull.Value; + row[11] = pas.PassengerPortOfDisembarkation ?? (object)DBNull.Value; + row[12] = pas.PassengerInTransit ?? (object)DBNull.Value; + row[13] = pas.Identifier ?? (object)DBNull.Value; + row[14] = pas.IsDeparture; + row[15] = pas.PassengerIdentityDocumentIssuingState ?? (object)DBNull.Value; + row[16] = pas.PassengerIdentityDocumentExpiryDate ?? (object)DBNull.Value; + row[17] = pas.NotificationSchengen ?? (object)DBNull.Value; + row[18] = pas.NotificationPAX ?? (object)DBNull.Value; + row[19] = pas.EmergencyCare ?? (object)DBNull.Value; + row[20] = pas.EmergencyContactNumber ?? (object)DBNull.Value; + row[21] = pas.PassengerCountryOfBirth ?? (object)DBNull.Value; + + result.Rows.Add(row); + } + + return result; + } + + #endregion + } #region class PASD