Skip to main content

Dynamic Systems - Usage Guide

Querying Extensible Data

Since EntityAttribute, EntityTag, and EntityMetadata use polymorphic relationships, you need to query them by EntityType and EntityId:

Querying EntityAttributes

// Get all attributes for a rod
var rodAttributes = context.EntityAttributes
.Where(ea => ea.EntityType == "Rod" && ea.EntityGuidId == rodId)
.ToList();

// Get specific attribute
var customAction = context.EntityAttributes
.FirstOrDefault(ea => ea.EntityType == "Rod"
&& ea.EntityGuidId == rodId
&& ea.AttributeKey == "CustomActionRating");

// Get numeric attributes
var numericAttrs = context.EntityAttributes
.Where(ea => ea.EntityType == "Rod"
&& ea.EntityGuidId == rodId
&& ea.AttributeType == AttributeType.Number)
.ToList();

Querying EntityMetadata

// Get metadata for a rod build
var buildMetadata = context.EntityMetadata
.Where(em => em.EntityType == "RodBuild"
&& em.EntityIntId == rodBuildId
&& em.MetadataKey == "BuildProcess")
.FirstOrDefault();

if (buildMetadata != null)
{
var buildData = JsonSerializer.Deserialize<BuildProcessData>(buildMetadata.JsonData);
}

Querying EntityTags

// Get all tags for a rod
var rodTags = context.EntityTags
.Where(et => et.EntityType == "Rod" && et.EntityGuidId == rodId)
.Include(et => et.Tag)
.ToList();

// Get tags by context
var useCaseTags = context.EntityTags
.Where(et => et.EntityType == "Rod"
&& et.EntityGuidId == rodId
&& et.Context == "UseCase")
.Include(et => et.Tag)
.ToList();

Querying LookupTables

// Get all rod power values
var rodPowers = context.LookupTables
.Where(lt => lt.Category == "RodPower" && lt.IsActive)
.OrderBy(lt => lt.DisplayOrder)
.ToList();

// Get custom (user-defined) values
var customPowers = context.LookupTables
.Where(lt => lt.Category == "RodPower"
&& !lt.IsSystemDefined
&& lt.IsActive)
.ToList();

Adding Custom Data

Adding Custom Attribute

var customAttr = new EntityAttribute
{
EntityType = "Rod",
EntityGuidId = rod.Id,
AttributeKey = "CustomActionRating",
NumericValue = 8.5m,
Unit = "out of 10",
AttributeType = AttributeType.Number,
IsUserDefined = true
};
context.EntityAttributes.Add(customAttr);

Adding Custom Metadata

var metadata = new EntityMetadata
{
EntityType = "RodBuild",
EntityIntId = rodBuild.Id,
MetadataKey = "BuildProcess",
SchemaVersion = "1.0",
SchemaType = "BuildProcess",
JsonData = JsonSerializer.Serialize(new {
Steps = new[] { /* ... */ },
ToolsUsed = new[] { /* ... */ }
})
};
context.EntityMetadata.Add(metadata);

Adding Custom Lookup Value

var customPower = new LookupTable
{
Category = "RodPower",
Name = "Super Heavy",
Code = "SuperHeavy",
IsSystemDefined = false,
DisplayOrder = 8,
IsActive = true
};
context.LookupTables.Add(customPower);

// Use in rod blank
rodBlank.Power = RodPower.UltraHeavy; // Closest enum
rodBlank.PowerLookupId = customPower.Id; // Custom value

Best Practices

  1. Use Enums for Standard Values: Keep enums for well-defined, stable categories
  2. Use Lookup Tables for Extensible Categories: Use lookup tables for categories that may grow
  3. Use EntityAttribute for Custom Properties: Use attributes for entity-specific custom fields
  4. Use EntityMetadata for Complex Data: Use metadata for nested/complex data structures
  5. Use EntityTag for Flexible Categorization: Use tags for multi-dimensional categorization
  6. Query by EntityType + EntityId: Always filter by both EntityType and EntityId when querying
  7. Index Performance: The indexes ensure fast queries on EntityType + EntityId combinations