Entity Framework Core,
against a schema that is alive.
DataOil.EntityFrameworkCore lets a .NET team keep its ordinary
DbContext and LINQ. It learns each database's schema when it connects, checks your
model against it, translates your queries into Data Oil's own language, and sends them through
the same door as every other call — so every permission, meter and audit line applies.
Shipped in September 2026
What it does for a .NET team
Your own DbContext
Ordinary strongly typed classes and LINQ. The provider knows the name of no table or column in any database; it learns each one's schema when your context first reaches it.
Checked, not assumed
Your model is compared with the schema as it is today. Every disagreement is reported at once, by name, rather than read as nulls or found at the first failing query.
A schema that moves
Ingestion adds properties as data arrives. A change your model still holds against is followed on the next statement; one it does not is refused, naming both versions.
Saves that cannot overwrite
Every update and delete is guarded by the record's version, so two people saving the same record cannot both win: the second is told.
Migrations that look first
Before a migration changes anything, it checks that the schema is still the one it was written against, and refuses rather than overwrite what something else changed.
What EF cannot express
Fields no schema declares, graph traversals and vector search run beside EF, over the same connection and in the same transaction.
What was proved, and howFor the technically minded
Every line below runs against the real engine every time the provider is built, and the packaged provider was then run, unchanged, against a deployed system.
| Area | Proved |
|---|---|
| Queries | filters, sorting, paging, projection, grouping, aggregates, joins, Include, Any() over a relationship |
| Writes | insert, update and delete, each reading back what the engine assigned |
| Concurrency | a lost update and a stale delete are refused and change nothing |
| Transactions | a rolled-back unit leaves nothing; a committed one leaves everything |
| Types | exact decimals, UTC instants, dates, GUIDs, enums, binary |
| Schemas | four databases with nothing in common, one compiled provider |
| Migrations | applied once, recorded, fenced against a second process, refused on drift |
| Guardrails | creating and dropping a database only as your credentials allow |
| LINQPad 9 | a connection to a deployed database, its types browsable and queryable with typed LINQ, giving the answers the provider gives |
Connecting
One package, one connection string
What you install
DataOil.EntityFrameworkCore for .NET 10, from Data Oil's own package directory
beside the client packages. It brings the .NET client and Entity Framework Core with it.
What you point it at
Your deployment's address, the database by name, and a Data Oil account or API key — the same credential your other applications use, with the same rights.
In LINQPad 9
Point, connect, query
The Data Oil driver for LINQPad 9 turns a connection into a typed context the moment it connects: every type your credential may read becomes a table you can browse and query with LINQ, with no classes written first. The statements it sends appear in the SQL tab.
How it names things, and what it needsFor the technically minded
- Built on the provider.
DataOil.LINQPadreads the schema as your credential may read it, writes and compiles a context from it, and fills LINQPad's schema tree with each type's properties, its indexes, and what it cannot map. - Names you can type.
CustomersofCustomer, and a name C# cannot spell becomes the nearest one -App_Usage_Time_min_dayforApp Usage Time (min/day)- while still reading the column the database has. - The engine's own language beside LINQ, over the same connection, for properties no schema declares, graph traversals and vector search.
- LINQPad 9 only. The provider runs on .NET 10, which LINQPad 8 cannot. It installs from the same package directory as the provider.
Said plainly
What it says no to, and what to use instead
A query the provider cannot send as Data Oil's own is refused, with the reason, rather than run on your machine over every row.
The four things it declinesAnd what to do instead
- A subquery per row that is not a single match — such as counting each customer's orders in a projection. Count with a join and a grouping, or load the related records and count them.
Any()over a relationship is a single match and runs. CROSS APPLYandOUTER APPLY— rewrite the query as a join, or useInclude.- An isolation level other than snapshot — every transaction runs at snapshot isolation, which is what Data Oil offers.
- Renaming a property in a migration — add the new property, copy the values, drop the old one.
Next
Bring your own model.
The proof of concept can start with your team's own classes against your own data.
Get started Contact