Browse Source

Improved speed of CoreTable.LoadRows

Kenric Nugteren 1 năm trước cách đây
mục cha
commit
e3d01aac55

+ 21 - 9
InABox.Core/CoreTable/CoreRow.cs

@@ -33,7 +33,7 @@ namespace InABox.Core
         protected internal CoreRow(CoreTable owner)
         {
             Table = owner;
-            Values = new List<object?>();
+            Values = new List<object?>(owner.Columns.Count);
         }
 
         public static CoreRow[] None
@@ -191,10 +191,16 @@ namespace InABox.Core
 
         public void Set<T>(int col, T value)
         {
-            while (Values.Count <= col)
-                Values.Add(Table.Columns[Values.Count].DataType.GetDefault());
-
-            Values[col] = value;
+            if(Values.Count <= col)
+            {
+                while (Values.Count < col)
+                    Values.Add(Table.Columns[Values.Count].DataType.GetDefault());
+                Values.Add(value);
+            }
+            else
+            {
+                Values[col] = value;
+            }
         }
         
         public void Set<T>(string columnname, T value)
@@ -203,10 +209,16 @@ namespace InABox.Core
             if (col < 0)
                 throw new Exception("Column not found: " + columnname);
 
-            while (Values.Count <= col)
-                Values.Add(Table.Columns[Values.Count].DataType.GetDefault());
-
-            Values[col] = value;
+            if(Values.Count <= col)
+            {
+                while (Values.Count < col)
+                    Values.Add(Table.Columns[Values.Count].DataType.GetDefault());
+                Values.Add(value);
+            }
+            else
+            {
+                Values[col] = value;
+            }
 
             //this.RowObject.SetValue(columnname, value);
         }

+ 29 - 13
InABox.Core/CoreTable/CoreTable.cs

@@ -36,6 +36,9 @@ namespace InABox.Core
             }
         }
 
+        [field: NonSerialized]
+        public IList<Func<object, object?>?> Getters { get; } = new List<Func<object, object?>?>();
+
         [field: NonSerialized]
         public Dictionary<string, IList<Action<object, object>?>> Setters { get; } = new Dictionary<string, IList<Action<object, object>?>>();
 
@@ -99,9 +102,7 @@ namespace InABox.Core
         {
             foreach (var obj in objects)
             {
-                var row = NewRow();
-                LoadRow(row, obj);
-                Rows.Add(row);
+                LoadRow(obj);
             }
         }
 
@@ -110,7 +111,7 @@ namespace InABox.Core
             foreach (var row in rows)
             {
                 var newrow = NewRow();
-                LoadRow(newrow, row);
+                FillRow(newrow, row);
                 Rows.Add(newrow);
             }
         }
@@ -127,24 +128,34 @@ namespace InABox.Core
             }
         }
 
-        public void LoadRow(CoreRow row, object obj)
+        public void FillRow(CoreRow row, object obj)
         {
-            foreach (var col in Columns)
+            var bFirst = Getters.Count == 0;
+
+            for(var i = 0; i < Columns.Count; ++i)
+            {
                 try
                 {
-                    //var prop = DataModel.Property(obj.GetType(), col.ColumnName);
-                    //if (prop is CustomProperty)
-                    //    prop is CustomProperty ? item.UserProperties[key] : CoreUtils.GetPropertyValue(item, key);
-                    var fieldvalue = CoreUtils.GetPropertyValue(obj, col.ColumnName);
-                    row[col.ColumnName] = fieldvalue;
+                    if (bFirst)
+                    {
+                        var prop = DatabaseSchema.Property(obj.GetType(), Columns[i].ColumnName);
+                        Getters.Add(prop?.Getter());
+                    }
+
+                    var getter = Getters[i];
+                    if (getter != null)
+                        row.Set(i, getter(obj));
+                    else
+                        row.Set(i, CoreUtils.GetPropertyValue(obj, Columns[i].ColumnName));
                 }
                 catch (Exception e)
                 {
                     Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
                 }
+            }
         }
 
-        public void LoadRow(CoreRow row, CoreRow from)
+        public void FillRow(CoreRow row, CoreRow from)
         {
             foreach (var col in Columns)
                 try
@@ -414,10 +425,15 @@ namespace InABox.Core
 
         #endregion
 
+        /// <summary>
+        /// Create a new row with data from <paramref name="obj"/>, and adds it to the table.
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <returns></returns>
         public CoreTable LoadRow(object obj)
         {
             var row = NewRow();
-            LoadRow(row, obj);
+            FillRow(row, obj);
             Rows.Add(row);
             return this;
         }

+ 1 - 3
InABox.Core/CoreUtils.cs

@@ -832,9 +832,7 @@ namespace InABox.Core
             var props = name.Split('.');
             foreach (var prop in props)
             {
-                var rprop = t.GetProperty(prop);
-                if (rprop == null)
-                    throw new Exception(string.Format("Property {0} does not exist for {1}", prop, o.GetType().Name));
+                var rprop = t.GetProperty(prop) ?? throw new Exception(string.Format("Property {0} does not exist for {1}", prop, o.GetType().Name));
                 o = rprop.GetValue(o, null);
                 if (o is null)
                     return null;

+ 1 - 3
InABox.Core/DataModel/DataModel.cs

@@ -318,9 +318,7 @@ namespace InABox.Core
             if (IsRequired<TType>(requiredtables))
                 foreach (var item in items)
                 {
-                    var row = table.NewRow();
-                    table.LoadRow(row, item);
-                    table.Rows.Add(row);
+                    table.LoadRow(item);
                 }
         }
 

+ 2 - 2
InABox.Core/ICoreTable.cs

@@ -20,8 +20,8 @@ namespace InABox.Core
         void Filter(Func<CoreRow, bool> predicate);
         void LoadColumns(Type T);
         void LoadDictionary<T, TKey, TValue>(Dictionary<TKey, TValue> dictionary, Expression<Func<T, TKey>> key, Expression<Func<T, TValue>> value);
-        void LoadRow(CoreRow row, CoreRow from);
-        void LoadRow(CoreRow row, object obj);
+        void FillRow(CoreRow row, CoreRow from);
+        void FillRow(CoreRow row, object obj);
         void LoadRows(IEnumerable<CoreRow> rows);
         void LoadRows(IEnumerable<object> objects);
         CoreRow NewRow(bool populate = false);

+ 2 - 4
InABox.Core/Imports/BaseImporter.cs

@@ -131,7 +131,7 @@ namespace InABox.Core
                             ClientFactory.CreateClient(lookuptype).Save(newlookup, "Created by Import");
                             lookupid = (Guid?)CoreUtils.GetPropertyValue(newlookup, "ID") ?? Guid.Empty;
                             var newrow = lookup.Results.NewRow();
-                            lookup.Results.LoadRow(newrow, newlookup);
+                            lookup.Results.FillRow(newrow, newlookup);
                             lookup.Results.Rows.Add(newrow);
                             CoreUtils.SetPropertyValue(item, lookup.ID, lookupid);
                             var prefix = String.Join(".", lookup.ID.Split('.').Reverse().Skip(1).Reverse());
@@ -361,9 +361,7 @@ namespace InABox.Core
 
                         if (bNewKey)
                         {
-                            var row = keylookup!.Results.NewRow();
-                            keylookup.Results.LoadRow(row, item);
-                            keylookup.Results.Rows.Add(row);
+                            keylookup!.Results.LoadRow(item);
                         }
 
                         var key = new List<object?>();

+ 1 - 1
InABox.Poster.Custom/InABox.Poster.Custom.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFramework>net6.0</TargetFramework>
+    <TargetFramework>net8.0</TargetFramework>
     <ImplicitUsings>enable</ImplicitUsings>
     <Nullable>enable</Nullable>
   </PropertyGroup>

+ 7 - 9
inabox.wpf/DynamicGrid/DynamicGrid.cs

@@ -1277,7 +1277,7 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
         if (MasterData is null) return;
 
         var masterrow = MasterData.NewRow();
-        MasterData.LoadRow(masterrow, row);
+        MasterData.FillRow(masterrow, row);
         Refresh(false, false);
     }
 
@@ -1285,9 +1285,7 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
     {
         if (MasterData is null) return;
 
-        var masterrow = MasterData.NewRow();
-        MasterData.LoadRow(masterrow, data);
-        MasterData.Rows.Add(masterrow);
+        MasterData.LoadRow(data);
         Refresh(false, false);
     }
 
@@ -1424,7 +1422,7 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
 
     protected virtual void DoEdit()
     {
-        if (!SelectedRows.Any())
+        if (SelectedRows.Length == 0)
             return;
 
         if (AddEditClick(SelectedRows))
@@ -1795,14 +1793,14 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
             //foreach (String key in VisualFilters.Keys)
             //    CoreUtils.SetPropertyValue(item, key, VisualFilters[key]);
 
-            if (EditItems(new[] { item }))
+            if (EditItems([item]))
             {
                 //_CurrentRow = Data.Rows.Count;
                 var row = Data.NewRow();
                 ObjectToRow(item, row);
                 Data.Rows.Add(row);
                 InvalidateGrid();
-                SelectedRows = new[] { row };
+                SelectedRows = [row];
                 DoChanged();
                 return true;
             }
@@ -1820,7 +1818,7 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
             sw.Stop();
         }
 
-        if (items.Any())
+        if (items.Length != 0)
         {
             var sel = SelectedRows;
             if (EditItems(items))
@@ -2031,7 +2029,7 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
 
     protected virtual void ObjectToRow(T obj, CoreRow row)
     {
-        row.Table.LoadRow(row, obj);
+        row.Table.FillRow(row, obj);
     }
 
     #region Import / Export

+ 1 - 2
inabox.wpf/DynamicGrid/DynamicItemsListGrid.cs

@@ -61,8 +61,7 @@ namespace InABox.DynamicGrid
         protected override void Reload(Filters<T> criteria, Columns<T> columns, ref SortOrder<T>? sort, Action<CoreTable?, Exception?> action)
         {
             var result = new CoreTable();
-            result.LoadColumns(typeof(T));
-            
+            result.LoadColumns(columns);
             result.LoadRows(Items);
             action.Invoke(result, null);
         }

+ 1 - 1
inabox.wpf/DynamicGrid/Editors/JsonEditor/JsonEditorControl.cs

@@ -50,7 +50,7 @@ namespace InABox.DynamicGrid
                 row = Data.Rows[rowindex];
             }
 
-            Data.LoadRow(row, item);
+            Data.FillRow(row, item);
         }
     }