瀏覽代碼

The LoadForeignProperties function. Might not want to pull yet.

Kenric Nugteren 1 年之前
父節點
當前提交
dfc6bbe47c
共有 1 個文件被更改,包括 85 次插入0 次删除
  1. 85 0
      inabox.wpf/DynamicGrid/DynamicOneToManyGrid.cs

+ 85 - 0
inabox.wpf/DynamicGrid/DynamicOneToManyGrid.cs

@@ -317,6 +317,90 @@ namespace InABox.DynamicGrid
             }
         }
 
+        /// <summary>
+        /// Load the properties of any <see cref="EntityLink{T}"/>s on this <see cref="TMany"/> where the <see cref="IEntityLink.ID"/> is not <see cref="Guid.Empty"/>.
+        /// This allows us to populate columns of transient objects, as long as they are linked by the ID. What this actually then does is query each
+        /// linked table with the required columns.
+        /// </summary>
+        /// <param name="columns"></param>
+        private void LoadForeignProperties(Columns<TMany> columns)
+        {
+            // Lists of properties that we need, arranged by the entity link property which is their parent.
+            // LinkIDProperty : (Type, Properties: [(columnName, property)], Objects)
+            var newData = new Dictionary<IProperty, Tuple<Type, List<Tuple<string, IProperty>>, HashSet<TMany>>>();
+
+            foreach (var column in columns)
+            {
+                var property = DatabaseSchema.Property(typeof(TMany), column.Property);
+                if (property?.GetOuterParent(x => x.IsEntityLink) is IProperty linkProperty)
+                {
+                    var remaining = column.Property[(linkProperty.Name.Length + 1)..];
+                    if (remaining.Equals(nameof(IEntityLink.ID)))
+                    {
+                        // This guy isn't foreign, so we don't pull him.
+                        continue;
+                    }
+
+                    var idProperty = DatabaseSchema.Property(typeof(TMany), linkProperty.Name + "." + nameof(IEntityLink.ID))!;
+
+                    var linkType = linkProperty.PropertyType.GetInterfaceDefinition(typeof(IEntityLink<>))!.GenericTypeArguments[0];
+                    if (!newData.TryGetValue(idProperty, out var data))
+                    {
+                        data = new Tuple<Type, List<Tuple<string, IProperty>>, HashSet<TMany>>(
+                            linkType,
+                            new List<Tuple<string, IProperty>>(),
+                            new HashSet<TMany>());
+                        newData.Add(idProperty, data);
+                    }
+
+                    var any = false;
+                    foreach (var item in Items)
+                    {
+                        if (!item.LoadedColumns.Contains(column.Property))
+                        {
+                            var linkID = (Guid)idProperty.Getter()(item);
+                            if (linkID != Guid.Empty)
+                            {
+                                any = true;
+                                data.Item3.Add(item);
+                            }
+                        }
+                    }
+                    if (any)
+                    {
+                        data.Item2.Add(new(remaining, property));
+                    }
+                }
+            }
+
+            foreach (var (prop, data) in newData)
+            {
+                if (data.Item2.Any())
+                {
+                    var ids = data.Item3.Select(prop.Getter()).Cast<Guid>().ToArray();
+                    var table = Client.Create(data.Item1).Query(
+                        Filter.Create<Entity>(data.Item1, x => x.ID).InList(ids),
+                        Columns.Create(data.Item1, data.Item2.Select(x => x.Item1).ToArray()).Add<Entity>(x => x.ID));
+                    foreach (var entity in data.Item3)
+                    {
+                        var linkID = (Guid)prop.Getter()(entity);
+                        var row = table.Rows.FirstOrDefault(x => x.Get<Entity, Guid>(x => x.ID) == linkID);
+                        if (row is not null)
+                        {
+                            foreach (var (name, property) in data.Item2)
+                            {
+                                if (!entity.LoadedColumns.Contains(property.Name))
+                                {
+                                    property.Setter()(entity, row[name]);
+                                    entity.LoadedColumns.Add(property.Name);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
         protected override void Reload(Filters<TMany> criteria, Columns<TMany> columns, ref SortOrder<TMany>? sort,
             Action<CoreTable?, Exception?> action)
         {
@@ -348,6 +432,7 @@ namespace InABox.DynamicGrid
                     }
                 }
             }
+            LoadForeignProperties(columns);
 
             if (sort != null)
             {