EntityHelper - pengdows/pengdows.crud GitHub Wiki
EntityHelper<TEntity, TRowID>
is the heart of pengdows.crud’s dynamic SQL mapping. It provides reflection-backed mapping between POCOs and SQL, enabling parameterized CRUD operations across supported databases.
EntityHelper<TEntity, TRowID>
is the primary utility in pengdows.crud for mapping entities to SQL. It uses reflection, precompiled accessors, and context-aware parameter and naming strategies to generate safe, efficient, portable SQL for CRUD operations.
- Generate parameterized SQL for INSERT, SELECT, UPDATE, and DELETE
- Map database results to POCOs using tracked readers
- Enforce database-specific rules and auditing
- Handle version fields and optimistic concurrency
var helper = new EntityHelper<User, Guid>(context, serviceProvider);
-
TEntity
your entity class -
TRowID
— the pseudokey type (typically int or Guid) -
context
— is the DatabaseContext that will be used to create sqlcontainers, sql wrapping characters, and parameters. -
serviceProvider
— is your dependency injection to grab additional items.
- Requires exactly one
[Id]
property - Supports multi-column
[PrimaryKey]
fields - Supports
[Version]
field for optimistic concurrency - Handles
[CreatedBy]
,[CreatedOn]
,[LastUpdatedBy]
,[LastUpdatedOn]
automatically via DI using the Audit Handling
-
BuildCreate(entity)
— generates INSERT -
BuildRetrieve(ids)
— generates SELECT WHERE ID IN (...) -
BuildRetrieve(entities)
— generates SELECT with composite PK filters -
BuildUpdateAsync(entity)
— generates UPDATE (optionally checks version) -
BuildDelete(id)
— generates DELETE
- Uses
ITrackedReader
(extendsIDataReader
) for safe disposal - Uses cached compiled setters for high-performance hydration
- Applies
TypeCoercionHelper
for cross-database coercion (e.g., string→enum)
- Fields marked with
[CreatedBy]
,[CreatedOn]
, etc. are auto-filled - Uses registered
IAuditContextProvider<T>
from DI - Populated on insert or update
- All timestamps assumed to be UTC
-
BuildUpdateAsync(entity, loadOriginal: true)
compares current values to a reloaded original row - Columns that haven't changed will not be included in the UPDATE
- This improves performance and avoids race conditions on unnecessary writes
- Columns marked as
[CreatedBy]
or[CreatedOn]
are always excluded from updates to preserve audit traceability - Version fields are incremented automatically during updates
- If present, update WHERE clauses include
Version = ?
checks to enforce optimistic concurrency
- Automatically generates parameter names using
MakeParameterName
- Follows provider’s requirements for
@name
,:name
, or?
- Checks against
MaxParameterLimit
before issuing bulk WHEREs
- Use
BuildRetrieve
with object lists for composite key filters - Use
BuildUpdateAsync(..., loadOriginal: true)
to skip unchanged fields - Catch
TooManyParametersException
for wide filters on constrained databases - Subclass for custom query helpers (e.g.,
FindByEmail
)
- Only one
[Id]
property is allowed -
[PrimaryKey]
fields must not overlap with[Id]
, audit fields, or[Version]
- Requires a unique pseudokey per table to use EntityHelper auto-SQL