pub struct DbContext { /* private fields */ }Expand description
The session / unit-of-work entry point.
Entity sets are lazy-created via ctx.set::<T>(). Metadata is loaded from
the process-level MetadataCache on DbContextOptions (built once per
context_key, then Arc-shared). save_changes() commits all pending
changes in a transaction.
Implementations§
Source§impl DbContext
impl DbContext
Sourcepub fn from_options(options: &DbContextOptions) -> EFResult<Self>
pub fn from_options(options: &DbContextOptions) -> EFResult<Self>
Creates the context from options (uses the provider factory stored in options).
Entity metadata is loaded from the process-level MetadataCache on
DbContextOptions — inventory::iter + IEntityTypeConfiguration::configure()
run once per context_key (first call), then the result is Arc-shared
across all DbContext instances. Per-instance ModelBuilder mutations
(has_query_filter, etc.) after construction only affect this instance.
pub fn set<T>(&mut self) -> &mut DbSet<T>where
T: IEntityType + IEntitySnapshot + IGetKeyValues + IFromRow + INavigationSetter + Send + Sync + 'static,
Sourcepub fn model(&mut self) -> &mut ModelBuilder
pub fn model(&mut self) -> &mut ModelBuilder
Returns the model builder for Fluent API configuration.
Sourcepub fn model_builder(&self) -> &ModelBuilder
pub fn model_builder(&self) -> &ModelBuilder
Returns a read-only reference to the model builder.
Sourcepub fn entity_metas_contains<T: IEntityType>(&self) -> bool
pub fn entity_metas_contains<T: IEntityType>(&self) -> bool
Returns true if an entity of type T has been discovered and
registered in the entity metadata map.
Sourcepub fn discover_entities(&mut self) -> EFResult<()>
pub fn discover_entities(&mut self) -> EFResult<()>
No-op since metadata caching was introduced.
Historically, this method iterated inventory::iter to register entity
metadata and apply #[entity(T)] configurations. That work now happens
in MetadataCache::build(), invoked lazily by from_options() via
MetadataCache::get_or_build(). The result is Arc-shared across all
DbContext instances with the same context_key.
Retained as a public method for backward compatibility — existing code
calling ctx.discover_entities()? after from_options() continues to
compile and run (as a no-op). The metadata is already populated.
Sourcepub fn detect_changes(&mut self)
pub fn detect_changes(&mut self)
Detects changes on all tracked DbSets by comparing property snapshots.
Sourcepub async fn ensure_created(&self) -> EFResult<()>
pub async fn ensure_created(&self) -> EFResult<()>
Creates all tables for registered entity types.
Sources metas from model_builder.build(), which applies all Fluent
API configurations and #[entity(T)] overrides. Entities are
discovered automatically via #[derive(EntityType)]; call
discover_entities() first, or use set::<T>() to register manually.
Sourcepub async fn ensure_deleted(&self) -> EFResult<()>
pub async fn ensure_deleted(&self) -> EFResult<()>
Drops all tables for registered entity types.
Source§impl DbContext
impl DbContext
Sourcepub fn provider(&self) -> &dyn IDatabaseProvider
pub fn provider(&self) -> &dyn IDatabaseProvider
Returns the database provider.
Sourcepub fn change_tracker(&self) -> &ChangeTracker
pub fn change_tracker(&self) -> &ChangeTracker
Returns a read-only reference to the change tracker.
Sourcepub fn change_tracker_mut(&mut self) -> &mut ChangeTracker
pub fn change_tracker_mut(&mut self) -> &mut ChangeTracker
Returns a mutable reference to the change tracker.
Sourcepub fn clear_tracking(&mut self)
pub fn clear_tracking(&mut self)
Detaches every tracked entity and clears the change tracker.
Call this after a rollback when the handler is not going to retry, so
the rolled-back entities cannot leak into a later save_changes.
Entity instances themselves are not modified — only the context’s
tracking state is dropped.
Sourcepub async fn sql_query<T: IFromRow + IEntityType>(
&self,
sql: &str,
params: &[DbValue],
) -> EFResult<Vec<T>>
pub async fn sql_query<T: IFromRow + IEntityType>( &self, sql: &str, params: &[DbValue], ) -> EFResult<Vec<T>>
Executes a raw SQL query and materializes the result rows into entities.
This is the escape hatch for complex queries (multi-table JOINs, CTEs, window functions) that are hard to express via LINQ. The caller is responsible for SQL correctness and parameterization.
§Example
let blogs: Vec<Blog> = ctx
.sql_query("SELECT * FROM blogs WHERE id = ?", &[DbValue::I32(1)])
.await?;Sourcepub async fn begin_transaction(&mut self) -> EFResult<Box<dyn ITransaction>>
pub async fn begin_transaction(&mut self) -> EFResult<Box<dyn ITransaction>>
Begins a context-scoped transaction and returns its handle.
This is the EF Core-style API: the transaction is registered on the
context, so queries, navigation loading, bulk DML, raw SQL and
save_changes() all use the transaction connection. Nothing is
committed or rolled back until the returned handle is consumed.
let txn = ctx.begin_transaction().await?;
ctx.add::<Account>(account);
ctx.save_changes().await?; // joins, does not commit
txn.commit().await?; // or txn.rollback().await?Dropping the handle without committing rolls back (best effort). Nested transactions are not supported.
Sourcepub async fn begin_transaction_with(
&mut self,
isolation: IsolationLevel,
) -> EFResult<Box<dyn ITransaction>>
pub async fn begin_transaction_with( &mut self, isolation: IsolationLevel, ) -> EFResult<Box<dyn ITransaction>>
Like DbContext::begin_transaction, with an isolation level applied
at transaction start.
Sourcepub async fn use_transaction<F, R>(&mut self, f: F) -> EFResult<R>
pub async fn use_transaction<F, R>(&mut self, f: F) -> EFResult<R>
Executes a closure within a context-scoped transaction.
Registers the transaction on the context session for the duration of
f, so every statement issued through the context — queries, navigation
loading, bulk DML, raw SQL and save_changes() — reuses the same
transaction connection. Commits on Ok, rolls back on Err.
For a business rejection that must roll back and still return a value,
use the manual DbContext::begin_transaction handle and call
rollback() explicitly.
The closure receives &mut DbContext and must return a pinned boxed
future. This signature works around Rust’s async borrow checker by
letting the closure capture ctx by mutable reference while still
producing a Send future.
§Example
ctx.use_transaction(|ctx| Box::pin(async move {
ctx.add::<Blog>(blog);
ctx.save_changes().await?;
Ok(())
})).await?;Sourcepub async fn use_transaction_with<F, R>(
&mut self,
isolation: IsolationLevel,
f: F,
) -> EFResult<R>
pub async fn use_transaction_with<F, R>( &mut self, isolation: IsolationLevel, f: F, ) -> EFResult<R>
Like DbContext::use_transaction, with an explicit isolation level
applied at transaction start.
Source§impl DbContext
impl DbContext
Sourcepub fn add<T>(&mut self, entity: T)where
T: IEntityType + IEntitySnapshot + IGetKeyValues + IFromRow + INavigationSetter + Send + Sync + 'static,
pub fn add<T>(&mut self, entity: T)where
T: IEntityType + IEntitySnapshot + IGetKeyValues + IFromRow + INavigationSetter + Send + Sync + 'static,
Adds a new entity in Added state. The entity will be INSERTed during
save_changes().
Sourcepub fn attach<T>(&mut self, entity: T)where
T: IEntityType + IEntitySnapshot + IGetKeyValues + IFromRow + INavigationSetter + Send + Sync + 'static,
pub fn attach<T>(&mut self, entity: T)where
T: IEntityType + IEntitySnapshot + IGetKeyValues + IFromRow + INavigationSetter + Send + Sync + 'static,
Attaches an existing entity in Unchanged state with a snapshot for
future change detection.
Sourcepub fn update<T>(&mut self, entity: T)where
T: IEntityType + IEntitySnapshot + IGetKeyValues + IFromRow + INavigationSetter + Send + Sync + 'static,
pub fn update<T>(&mut self, entity: T)where
T: IEntityType + IEntitySnapshot + IGetKeyValues + IFromRow + INavigationSetter + Send + Sync + 'static,
Marks an entity as Modified — all fields will be UPDATEd during
save_changes().
Sourcepub fn upsert<T>(&mut self, entity: T)where
T: IEntityType + IEntitySnapshot + IGetKeyValues + IFromRow + INavigationSetter + Send + Sync + 'static,
pub fn upsert<T>(&mut self, entity: T)where
T: IEntityType + IEntitySnapshot + IGetKeyValues + IFromRow + INavigationSetter + Send + Sync + 'static,
Marks an entity for upsert (INSERT … ON CONFLICT DO UPDATE).
Sourcepub fn remove_at<T>(&mut self, index: usize) -> EFResult<()>where
T: IEntityType + IEntitySnapshot + IGetKeyValues + IFromRow + INavigationSetter + Send + Sync + 'static,
pub fn remove_at<T>(&mut self, index: usize) -> EFResult<()>where
T: IEntityType + IEntitySnapshot + IGetKeyValues + IFromRow + INavigationSetter + Send + Sync + 'static,
Marks the entity at the given index as Deleted.
Sourcepub fn remove_all<T>(&mut self)where
T: IEntityType + IEntitySnapshot + IGetKeyValues + IFromRow + INavigationSetter + Send + Sync + 'static,
pub fn remove_all<T>(&mut self)where
T: IEntityType + IEntitySnapshot + IGetKeyValues + IFromRow + INavigationSetter + Send + Sync + 'static,
Marks all entities of type T as Deleted.
Sourcepub async fn load_all<T>(&mut self) -> EFResult<()>where
T: IEntityType + IEntitySnapshot + IGetKeyValues + IFromRow + INavigationSetter + ILazyInit + Send + Sync + 'static,
pub async fn load_all<T>(&mut self) -> EFResult<()>where
T: IEntityType + IEntitySnapshot + IGetKeyValues + IFromRow + INavigationSetter + ILazyInit + Send + Sync + 'static,
Loads all rows from the database into the DbSet as Unchanged.
Clears existing entries and tracker state for type T first.
Source§impl DbContext
impl DbContext
Sourcepub async fn save_changes(&mut self) -> EFResult<SaveChangesResult>
pub async fn save_changes(&mut self) -> EFResult<SaveChangesResult>
Saves all pending changes across all DbSets.
Detects changes, runs interceptors, executes INSERT/UPDATE/DELETE in a transaction, and clears tracked entries on success.