Separate POCO defaults from value-expression evaluation in TableOperations#37
Separate POCO defaults from value-expression evaluation in TableOperations#37ritchiecarroll wants to merge 1 commit into
Conversation
…ttribute application.
|
Here is an example of a commonly used [DefaultValueExpression("DateTime.UtcNow")]
public DateTime CreatedOn { get; set; }The changes here suggest that we cannot support any default value expressions if we don't depend on all of the type registry's defaults in their entirety. As a result, various database models will not be automatically populated with database defaults when using Furthermore, I would argue that our C# models should, first and foremost, reflect the database they're modelling. Second, that dependencies should be hooked by the application rather than expected by the library. The way I see it, this PR intends to continue having the library expect dependencies so long as the application opts in. However, a quick look at the related PRs shows that it's still trivially easy to hide the dependency behind a convenience method, such as |
Summary
Decouples
TableOperations<T>from theGemstone.Expressionstype registry so the common "just construct and go" case works without any external setup.Previously,
TableOperations<T>.NewRecord()always evaluated attribute-based value expressions (DefaultValueExpressionAttribute/UpdateValueExpressionAttribute) against the type registry. When a model expression referenced an uninitialized dependency (e.g.Settings), simple usage such asnew TableOperations<Device>(connection).NewRecord()would throw — an unknowable hidden dependency for a casual user.Changes
TableOperations<T>is now pure POCO. It honors only the standardSystem.ComponentModel.DefaultValueAttributevia a self-contained compiled applier built withSystem.Linq.Expressions— no type-registry /Settingscoupling. Removed the expression scope, the three expression delegates,InitializeType(), and the staticTypeRegistryproperty.ExpressionTableOperations<T> : TableOperations<T>is the opt-in surface that restores the full value-expression behavior (a strict superset, identical to the prior default). Callers using it own the responsibility of initializing any dependencies their expressions reference.protected virtualseams (CreateRecordInstance,ApplyRecordDefaultValues,ApplyRecordUpdateValues) that the derived type overrides.SecureTableOperations<T>now wrapsExpressionTableOperations<T>to preserve existing behavior.Verification
Gemstone.Databuilds clean (0 errors).TableOperationsDefaultsTest) confirm: baseNewRecord()applies[DefaultValue]but does not evaluate expressions;ExpressionTableOperations<T>.NewRecord()evaluates both.Breaking change
External callers relying on the base
TableOperations<T>to auto-evaluate value expressions must switch toExpressionTableOperations<T>.Related PRs
This is the core library change. Consumer updates:
ExpressionTableOperations<T>in web model controllersExpressionTableOperations<T>in timeseries model operations🤖 Generated with Claude Code