Most enterprise applications transform data many times before the user can see it, edit it, validate it, and save it.

A database row becomes an ORM entity. The ORM entity becomes a DTO. The DTO becomes JSON. JSON becomes a frontend model. The frontend model becomes form state. Then the same path must be reversed to save changes back to the database.

A typical layered flow looks like this:

SQL Row
 -> ORM Entity
 -> DTO
 -> API Contract
 -> JSON
 -> UI Model
 -> Form State
 -> Save DTO
 -> Mapper
 -> ORM Entity
 -> SQL Row

Every step adds code.

Every step adds a place where names, types, nullability, validation, and state can drift.

ITS Framework uses a different model:

The DataRow is the entity.

The framework creates a direct tube from the database to the client runtime and back:

SQL Server
 -> Stored Procedure
 -> DataSet
 -> DataTable
 -> DataRow
 -> WinForms Binding
 -> Grid / Editor
 -> Modified DataRow
 -> UDTT
 -> Stored Procedure
 -> SQL Server

The row stays alive through the full cycle.

It is loaded, displayed, edited, validated, tracked, serialized, and saved without becoming five different models.

The Core Idea

In ITS Framework, DataRow is not treated as a temporary database container.

It is the runtime entity.

A DataRow already carries many capabilities that enterprise systems often rebuild manually:

Values
Types
Column metadata
Original values
Current values
Change tracking
Row state
Errors
Relations
Expressions
Serialization support
Binding support

That means the framework does not need to create a C# class for every table.

It does not need a DTO for every screen.

It does not need a mapper for every stored procedure result.

The database defines the shape.

The DataTable carries the schema.

The DataRow carries the entity.

The framework carries the behavior.

A Tube, Not a Translation Layer

The key architectural difference is that ITS Framework does not treat the database and UI as separate worlds that must constantly translate into each other.

Instead, it creates a controlled tube:

Database shape
    flows into
DataSet shape
    flows into
UI shape
    flows back into
Database save shape

The framework does not ask:

How do I convert this database row into a C# object?
How do I convert this object into a DTO?
How do I convert this DTO into a UI model?
How do I convert this UI model back into SQL?

It asks simpler questions:

What row is this?
What columns does it have?
What changed?
What errors exist?
What needs to be saved?

That is a shorter path with fewer synchronization points.

Why This Works in ITS Framework

This pattern works because of the deployment model.

The ITS Framework desktop runtime targets .NET 10 for Windows and runs as a WinForms application on an application server close to SQL Server. Users connect through RDP/RDS.

The user does not download data to a browser.

The user sees pixels.

User
 -> RDP/RDS
 -> App Server
 -> SQL Server over LAN

Because the application server is near SQL Server, the framework does not need an HTTP/JSON layer between the UI and the database.

There is no need to build a REST API just to move data from one trusted internal layer to another.

In this architecture, DataSet, DataTable, and DataRow are not legacy objects.

They are the right transport and runtime model.

The Row Carries State

A major advantage of DataRow is that it already knows its state.

A row can be:

Unchanged
Added
Modified
Deleted
Detached

The framework does not need to manually track every edit in a separate change tracker.

The row already knows.

It also keeps value versions:

Original value
Current value
Proposed value

That matters for enterprise screens.

The system can know:

What did the database send?
What did the user change?
What is new?
What was deleted?
What must be saved?

without creating a separate state model.

The UI Binds to the Entity Directly

WinForms already understands DataTable and DataRow.

That is a key advantage.

A grid can bind to a DataTable.

An editor can bind to a DataRow.

A validation system can inspect the same row.

A save operation can collect the changed rows.

The runtime entity is the same object throughout the UI:

DataRow
 -> Grid row
 -> Editor fields
 -> Validation status
 -> Change tracking
 -> Save payload

There is no duplicated frontend model.

There is no mismatch between what the grid displays and what the save process sees.

The row is the source.

Dynamic UI Without DTOs

In many systems, adding a field requires changes in several layers:

1. Add SQL column
2. Update ORM entity
3. Update DTO
4. Update mapper
5. Update API contract
6. Update frontend model
7. Update validation model
8. Update save command
9. Update UI binding

In ITS Framework, the database shape flows through the framework.

If a stored procedure returns a new column and the framework conventions allow it, the UI can discover it dynamically:

1. Add column
2. Return column in SELECT
3. Framework receives it in DataTable
4. Grid/editor can use it

Configuration can still control visibility, style, validation, editability, or layout.

But the field does not need to be recreated as a class property in every layer.

That is the power of DataRow as entity.

Validation Stays Near the Row

A DataRow can carry errors.

A DataTable can carry expressions.

The framework can use this to connect validation, command enablement, and UI status without creating a separate validation model.

For example:

DataRow values change
 -> DataColumn.Expression recalculates
 -> status changes
 -> command enablement changes
 -> UI updates

The row is not passive.

It participates in the rule system.

That makes validation more declarative and less dependent on duplicated code.

Saving Without Object Mapping

When the user saves, the framework already has the changed rows.

It does not need to reconstruct the save payload from UI controls.

The data is already in the DataRow.

The changed rows can be sent back through structured database mechanisms such as UDTTs and stored procedures.

The cycle becomes:

User edits grid/editor
 -> DataRow changes
 -> DataRowState tracks change
 -> Changed rows collected
 -> UDTT sent to stored procedure
 -> SQL Server applies changes

This is direct and database-native.

No object mapper is needed.

The Database Remains the Contract

This pattern works because the database is the contract.

The database defines:

Columns
Types
Relationships
Stored procedure result shapes
Save contracts
Validation inputs
Configuration metadata

The framework does not fight that.

It embraces it.

Instead of duplicating the database contract in C# classes, DTOs, API schemas, and frontend models, the framework carries the database contract forward using DataSet, DataTable, and DataRow.

The result is less duplication.

Less duplication means fewer synchronization bugs.

The Anti-Mapper Pattern

Mapping is not free.

Every mapper introduces questions:

Is this field included?
Is the type correct?
Is null handled correctly?
Is the name the same?
Is this read-only?
Is this calculated?
Is this original or current value?
Is this field saved back?

In many applications, mapping code becomes invisible infrastructure that quietly consumes development time.

ITS Framework avoids much of that by keeping the same runtime entity.

The row from the database remains the row in the UI.

The changed row becomes the save input.

This is not anti-architecture.

It is architecture optimized for the deployment model.

Resolving the Object-Relational Impedance Mismatch

The object-relational impedance mismatch appears when an application tries to represent relational data as a conventional object model. The two models organize information differently:

Relational world                 Object-oriented world
------------------------------   ------------------------------
Tables and rows                  Classes and objects
Primary and foreign keys         Object identity and references
Joins                            Navigable object graphs
NULL                             Language-specific null semantics
Set-based operations             Object-by-object behavior
Normalized relationships         Nested collections
Row versions and transactions    In-memory mutable state

An ORM attempts to bridge that mismatch. It maps tables to classes, columns to properties, foreign keys to references, and query results to object graphs. That bridge can be useful, but it also creates a permanent translation boundary. The system must decide how relational identity becomes object identity, when relationships are loaded, how NULL behaves, how object changes become SQL updates, and how both models remain synchronized.

ITS Framework resolves the problem differently:

The object is the row.

The framework does not force relational data into a second, competing representation. A DataRow is an object in the .NET runtime, but its semantics remain relational. It has typed columns, belongs to a DataTable, participates in DataRelation relationships, preserves value versions, and carries DataRowState through the edit-and-save cycle.

SQL row identity       -> DataRow in a DataTable
Column                 -> Typed DataColumn value
Foreign-key relation   -> DataRelation
Database NULL          -> DBNull
Original/current data  -> DataRowVersion
Insert/update/delete   -> DataRowState
Result set             -> DataTable
Related result sets    -> DataSet

There is no point at which a row must pretend to be a domain object with a different identity, relationship model, or state tracker. The relational shape survives inside the client runtime.

This removes several common mismatch problems:

No table-to-class mapping
No column-to-property synchronization
No object identity map
No lazy-loading boundary
No object-graph reconstruction
No separate change tracker
No translation from object state back to row state

Relationships also remain explicit and relational. A parent and its children do not need to become a custom aggregate object merely so the UI can navigate them. They can remain related tables inside a DataSet, connected through keys and DataRelation, while the framework supplies the behavior needed by grids, editors, validation, and commands.

The framework is still object-oriented where object orientation adds value: services, modules, controls, commands, configuration engines, and reusable behaviors are objects. What it avoids is converting tabular business data into custom classes merely to satisfy an architectural convention.

This distinction is important. ITS Framework does not solve the impedance mismatch by building a more sophisticated mapper. It removes the unnecessary mismatch from this part of the system:

The database remains relational.
The transport remains relational.
The runtime entity remains relational.
The UI binds to the relational entity.
The save contract remains relational.

The result is not that relational and object-oriented models have become identical. It is that the architecture no longer requires business data to cross repeatedly between them. The DataRow is the meeting point: a .NET object whose native meaning is a relational row.

Why This Is Different from an ORM

An ORM usually tries to make the database look like objects.

ITS Framework does something different.

It lets the database stay relational and lets the runtime model stay tabular.

That is important.

The framework is not trying to pretend that enterprise data is a pure object graph.

It uses:

DataSet   -> collection of related tables
DataTable -> tabular schema and rows
DataRow   -> runtime entity

This matches SQL Server naturally.

It also matches WinForms binding naturally.

The result is a database-native application platform.

Conventions Make the Tube Work

The DataRow as Entity pattern depends on conventions.

If column names are stable, lowercase, and predictable, the same row can move through SQL Server, DataTable, XML serialization, and UI binding without custom mapping.

If standard descriptors such as id, name, and descr mean the same thing everywhere, the framework and the team can infer intent.

If relationship columns consistently use patterns such as _id, the framework can understand keys without a mapping table.

If framework columns use prefixes such as csys_*, the engine can recognize internal behavior by name.

The tube works because the row is not ambiguous.

The naming convention becomes part of the transport contract.

Configuration Still Has a Role

DataRow as Entity does not mean everything is automatic.

Configuration still matters when intent cannot be inferred.

Configuration can define:

Which stored procedure loads the data
Which columns are visible
Which cell type edits a value
Which validation rule applies
Which master-detail relationship is active
Which command is enabled
Which report or module is opened

The difference is that configuration does not need to recreate the model.

The DataRow already carries the model.

Configuration describes behavior around the row.

Tradeoffs

This pattern is powerful, but it is not universal.

It works best when:

The application is internal or enterprise
The database is trusted as the contract
The UI can bind to tabular data
The app server is close to SQL Server
The system does not need public HTTP APIs for every operation
The framework controls the runtime environment

It may not be the best fit when:

The client is an untrusted browser app
The system requires public REST contracts
The domain model must be independent from the database
The application needs offline disconnected clients
The database schema is not stable or not authoritative

The point is not that DataRow should replace every entity model everywhere.

The point is that in the right architecture, DataRow can eliminate entire layers.

The Real Innovation

The innovative part is not simply using DataRow.

The innovative part is using it as the center of a complete platform:

Database contract
 -> DataSet transport
 -> DataRow entity
 -> WinForms binding
 -> Dynamic UI
 -> Validation
 -> Change tracking
 -> UDTT save
 -> Stored procedure execution

That creates a tube from SQL Server to the user interface and back.

The framework does not repeatedly translate the row.

It preserves it.

Final Principle

The idea can be summarized like this:

Do not create a new model when the row already carries the model.

Or:

**The database defines the shape.

The DataTable carries the schema.

The DataRow carries the entity.

The framework carries the behavior.**

That is the essence of DataRow as Entity.

It is not a shortcut.

It is a deliberate architectural choice.

Summary

ITS Framework avoids unnecessary model duplication by treating DataRow as the runtime entity.

The data flows through a direct tube:

SQL Server
 -> DataSet
 -> DataTable
 -> DataRow
 -> UI binding
 -> User edits
 -> Changed DataRow
 -> UDTT
 -> Stored procedure
 -> SQL Server

This removes many layers common in modern enterprise applications:

No ORM entity duplication
No DTO duplication
No mapper layer
No JSON contract between app and database
No separate UI model for every table
No manual change tracker

The result is a system where the database remains the contract, the row remains the entity, and the framework provides the behavior around it.

That is why DataRow as Entity is one of the most important patterns in ITS Framework.