Jelajahi Sumber

Added a "Loaded Columns" property, which keeps track of what columns a given object has, populated by ToObject.
Made Columns<T> IEnumerable.
Added EnsureColumns on client, and added CoreRow.FillObject

Kenric Nugteren 1 tahun lalu
induk
melakukan
86830e815f

+ 21 - 0
InABox.Core/BaseObject.cs

@@ -2,9 +2,11 @@
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.ComponentModel;
+using System.Data;
 using System.Linq;
 using System.Linq.Expressions;
 using System.Reflection;
+using System.Runtime.CompilerServices;
 using System.Runtime.Serialization;
 
 //using PropertyChanged;
@@ -57,6 +59,8 @@ namespace InABox.Core
         {
             CheckOriginalValues();
 
+            LoadedColumns = new HashSet<string>();
+
             UserProperties = new UserProperties();
             //UserProperties.ParentType = this.GetType();
             UserProperties.OnPropertyChanged += (o, n, b, a) =>
@@ -115,6 +119,10 @@ namespace InABox.Core
         [DoNotPersist]
         public ConcurrentDictionary<string, object?> OriginalValues { get; set; }
 
+        [DoNotPersist]
+        [DoNotSerialize]
+        public HashSet<string> LoadedColumns { get; set; }
+
         protected virtual void SetChanged(string name, object? before, object? after)
         {
             bChanged = true;
@@ -183,6 +191,8 @@ namespace InABox.Core
             if (name.Equals("OriginalValues"))
                 return;
 
+            LoadedColumns.Add(name);
+
             if (!HasChanged(before, after))
                 return;
 
@@ -366,6 +376,17 @@ namespace InABox.Core
 
     public static class BaseObjectExtensions
     {
+        public static bool HasColumn<T>(this T sender, string column)
+            where T : BaseObject
+        {
+            return sender.LoadedColumns.Contains(column);
+        }
+        public static bool HasColumn<T, TType>(this T sender, Expression<Func<T, TType>> column)
+            where T : BaseObject
+        {
+            return sender.LoadedColumns.Contains(CoreUtils.GetFullPropertyName(column, "."));
+        }
+
         public static bool HasOriginalValue<T>(this T sender, string propertyname) where T : BaseObject
         {
             return sender.OriginalValues != null && sender.OriginalValues.ContainsKey(propertyname);

+ 18 - 0
InABox.Core/Client/Client.cs

@@ -71,6 +71,24 @@ namespace InABox.Clients
             return ClientFactory.CreateClient<TEntity>();
         }
 
+        public static void EnsureColumns<TEntity>(TEntity entity, Columns<TEntity> columns)
+            where TEntity : Entity, IRemotable, IPersistent, new()
+        {
+            var newColumns = new Columns<TEntity>();
+            foreach(var column in columns)
+            {
+                if (!entity.HasColumn(column.Property))
+                {
+                    newColumns.Add(column);
+                }
+            }
+            if (newColumns.Any())
+            {
+                var row = Query(new Filter<TEntity>(x => x.ID).IsEqualTo(entity.ID), newColumns).Rows.FirstOrDefault();
+                row?.FillObject(entity);
+            }
+        }
+
         public static CoreTable Query<TEntity>(Filter<TEntity>? filter = null, Columns<TEntity>? columns = null, SortOrder<TEntity>? orderby = null)
             where TEntity : Entity, IRemotable, IPersistent, new()
         {

+ 13 - 2
InABox.Core/Column.cs

@@ -195,7 +195,7 @@ namespace InABox.Core
         }
     }
 
-    public class Columns<T> : IColumns
+    public class Columns<T> : IColumns, IEnumerable<Column<T>>
     {
         private readonly List<Column<T>> columns;
 
@@ -287,8 +287,9 @@ namespace InABox.Core
             return this;
         }
 
-        public Columns<T> AddSubColumns<TSub>(Expression<Func<T, TSub>> super, Columns<TSub> sub)
+        public Columns<T> AddSubColumns<TSub>(Expression<Func<T, TSub>> super, Columns<TSub>? sub)
         {
+            sub ??= CoreUtils.GetColumns(sub);
             var prefix = CoreUtils.GetFullPropertyName(super, ".") + ".";
             foreach(var column in sub.ColumnNames())
             {
@@ -560,6 +561,16 @@ namespace InABox.Core
         }
 
         #endregion
+
+        public IEnumerator<Column<T>> GetEnumerator()
+        {
+            return columns.GetEnumerator();
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return columns.GetEnumerator();
+        }
     }
     public static class ColumnSerialization
     {

+ 20 - 8
InABox.Core/CoreTable/CoreRow.cs

@@ -67,17 +67,16 @@ namespace InABox.Core
                 Set(columnName, value);
         }
 
-        public BaseObject ToObject(Type t)
+        public void FillObject(Type t, BaseObject obj)
         {
-            var entity = (Activator.CreateInstance(t) as BaseObject)!;
-            entity.SetObserving(false);
+            obj.SetObserving(false);
 
             if (!Table.Setters.TryGetValue("", out var setters))
             {
                 setters = new List<Action<object, object>?>();
                 Table.Setters[""] = setters;
             }
-            
+
             var bFirst = !setters.Any();
 
             for (var i = 0; i < Table.Columns.Count; i++)
@@ -94,9 +93,11 @@ namespace InABox.Core
 
                     var setter = setters[i];
                     if (setter != null && value != null)
-                        setter.Invoke(entity, value);
+                        setter.Invoke(obj, value);
                     else
-                        CoreUtils.SetPropertyValue(entity, column, value);
+                        CoreUtils.SetPropertyValue(obj, column, value);
+
+                    obj.LoadedColumns.Add(column);
                 }
                 catch (Exception e)
                 {
@@ -104,8 +105,19 @@ namespace InABox.Core
                 }
             }
 
-            entity.CommitChanges();
-            entity.SetObserving(true);
+            obj.CommitChanges();
+            obj.SetObserving(true);
+        }
+
+        public void FillObject<T>(T obj) where T : BaseObject
+        {
+            FillObject(typeof(T), obj);
+        }
+
+        public BaseObject ToObject(Type t)
+        {
+            var entity = (Activator.CreateInstance(t) as BaseObject)!;
+            FillObject(t, entity);
             return entity;
         }
 

+ 0 - 13
InABox.Database/Stores/DocumentStore.cs

@@ -4,19 +4,6 @@ namespace InABox.Database;
 
 public class DocumentStore : Store<Document>
 {
-    protected override void AfterLoad(IEnumerable<Document> items)
-    {
-        base.AfterLoad(items);
-        //if (!Provider.IsRelational())
-        //{
-        //    foreach (var item in items)
-        //    {
-        //        if ((item.Data == null) || (item.Data.Length == 0))
-        //            item.Data = Provider.LoadFile(item.ID);
-        //    }
-        //}
-    }
-
     protected override void OnSave(Document entity, ref string auditnote)
     {
         //if (!Provider.IsRelational())