Added automatic relation mapping
This commit is contained in:
@@ -79,10 +79,4 @@ public class PropertyConfig<TProp>(PropertyConfig config) {
|
||||
InnerConfig.DisplayValue = display;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PropertyConfig<TProp> IsRelation(bool isRelation) {
|
||||
InnerConfig.IsRelation = isRelation;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,8 +8,10 @@ namespace HopFrame.Core.Config;
|
||||
public class TableConfig {
|
||||
public Type TableType { get; }
|
||||
public string PropertyName { get; }
|
||||
public string DisplayName { get; set; }
|
||||
public DbContextConfig ContextConfig { get; }
|
||||
public bool Ignored { get; set; }
|
||||
internal bool Seeded { get; set; }
|
||||
|
||||
public List<PropertyConfig> Properties { get; } = new();
|
||||
|
||||
@@ -17,6 +19,7 @@ public class TableConfig {
|
||||
TableType = tableType;
|
||||
PropertyName = propertyName;
|
||||
ContextConfig = config;
|
||||
DisplayName = PropertyName;
|
||||
|
||||
foreach (var info in tableType.GetProperties()) {
|
||||
var propConfig = new PropertyConfig(info, this);
|
||||
@@ -55,6 +58,11 @@ public class TableConfig<TModel>(TableConfig config) {
|
||||
configurator.Invoke(prop);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TableConfig<TModel> SetDisplayName(string name) {
|
||||
InnerConfig.DisplayName = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
internal static PropertyInfo GetPropertyInfo<TSource, TProperty>(Expression<Func<TSource, TProperty>> propertyLambda) {
|
||||
if (propertyLambda.Body is not MemberExpression member) {
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace HopFrame.Core.Services;
|
||||
|
||||
public interface IContextExplorer {
|
||||
public IEnumerable<string> GetTableNames();
|
||||
public TableConfig? GetTable(string tableName);
|
||||
public TableConfig? GetTable(string tableDisplayName);
|
||||
public TableConfig? GetTable(Type tableEntity);
|
||||
public ITableManager? GetTableManager(string tableName);
|
||||
public ITableManager? GetTableManager(string tablePropertyName);
|
||||
}
|
||||
@@ -1,23 +1,26 @@
|
||||
using HopFrame.Core.Config;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace HopFrame.Core.Services.Implementations;
|
||||
|
||||
internal sealed class ContextExplorer(HopFrameConfig config, IServiceProvider provider) : IContextExplorer {
|
||||
internal sealed class ContextExplorer(HopFrameConfig config, IServiceProvider provider, ILogger<ContextExplorer> logger) : IContextExplorer {
|
||||
public IEnumerable<string> GetTableNames() {
|
||||
foreach (var context in config.Contexts) {
|
||||
foreach (var table in context.Tables) {
|
||||
if (table.Ignored) continue;
|
||||
yield return table.PropertyName;
|
||||
yield return table.DisplayName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TableConfig? GetTable(string tableName) {
|
||||
public TableConfig? GetTable(string tableDisplayName) {
|
||||
foreach (var context in config.Contexts) {
|
||||
var table = context.Tables.FirstOrDefault(table => table.PropertyName.Equals(tableName, StringComparison.CurrentCultureIgnoreCase));
|
||||
if (table is not null)
|
||||
return table;
|
||||
var table = context.Tables.FirstOrDefault(table => table.DisplayName.Equals(tableDisplayName, StringComparison.CurrentCultureIgnoreCase));
|
||||
if (table is null) continue;
|
||||
|
||||
SeedTableData(table);
|
||||
return table;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -26,16 +29,18 @@ internal sealed class ContextExplorer(HopFrameConfig config, IServiceProvider pr
|
||||
public TableConfig? GetTable(Type tableEntity) {
|
||||
foreach (var context in config.Contexts) {
|
||||
var table = context.Tables.FirstOrDefault(table => table.TableType == tableEntity);
|
||||
if (table is not null)
|
||||
return table;
|
||||
if (table is null) continue;
|
||||
|
||||
SeedTableData(table);
|
||||
return table;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public ITableManager? GetTableManager(string tableName) {
|
||||
public ITableManager? GetTableManager(string tablePropertyName) {
|
||||
foreach (var context in config.Contexts) {
|
||||
var table = context.Tables.FirstOrDefault(table => table.PropertyName == tableName);
|
||||
var table = context.Tables.FirstOrDefault(table => table.PropertyName == tablePropertyName);
|
||||
if (table is null) continue;
|
||||
|
||||
var dbContext = provider.GetService(context.ContextType) as DbContext;
|
||||
@@ -48,4 +53,20 @@ internal sealed class ContextExplorer(HopFrameConfig config, IServiceProvider pr
|
||||
return null;
|
||||
}
|
||||
|
||||
private void SeedTableData(TableConfig table) {
|
||||
if (table.Seeded) return;
|
||||
var dbContext = (provider.GetService(table.ContextConfig.ContextType) as DbContext)!;
|
||||
var entity = dbContext.Model.FindEntityType(table.TableType)!;
|
||||
|
||||
foreach (var key in entity.GetForeignKeys()) {
|
||||
var propConfig = table.Properties
|
||||
.SingleOrDefault(prop => prop.Info == key.DependentToPrincipal?.PropertyInfo);
|
||||
if (propConfig is null) continue;
|
||||
propConfig.IsRelation = true;
|
||||
}
|
||||
|
||||
logger.LogInformation("Extracted information for table '" + table.PropertyName + "'");
|
||||
table.Seeded = true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
@using HopFrame.Web.Components.Pages
|
||||
|
||||
<FluentDialogBody Style="overflow-x: auto">
|
||||
<HopFrameTablePage DisplayActions="false" DisplaySelection="true" TableName="@Content.SourceTable.PropertyName" PerPage="15" DialogData="Content" />
|
||||
<HopFrameTablePage DisplayActions="false" DisplaySelection="true" TableDisplayName="@Content.SourceTable.DisplayName" PerPage="15" DialogData="Content" />
|
||||
</FluentDialogBody>
|
||||
|
||||
@code {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@page "/admin/{TableName}"
|
||||
@page "/admin/{TableDisplayName}"
|
||||
@layout HopFrameLayout
|
||||
@rendermode InteractiveServer
|
||||
@implements IDisposable
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
<div style="display: flex; flex-direction: column; height: 100%">
|
||||
<FluentToolbar Class="hopframe-toolbar">
|
||||
<h3>@_config?.PropertyName</h3>
|
||||
<h3>@_config?.DisplayName</h3>
|
||||
<FluentButton
|
||||
IconStart="@(new Icons.Regular.Size16.ArrowClockwise())"
|
||||
OnClick="Reload"
|
||||
@@ -120,7 +120,7 @@
|
||||
@code {
|
||||
|
||||
[Parameter]
|
||||
public required string TableName { get; set; }
|
||||
public required string TableDisplayName { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool DisplaySelection { get; set; }
|
||||
@@ -145,9 +145,9 @@
|
||||
private int _selectedIndex = -1;
|
||||
|
||||
protected override void OnInitialized() {
|
||||
_config ??= Explorer.GetTable(TableName);
|
||||
_config ??= Explorer.GetTable(TableDisplayName);
|
||||
|
||||
if (_config is null) {
|
||||
if (_config is null || (_config.Ignored && DialogData is null)) {
|
||||
Navigator.NavigateTo("/admin", true);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user