Skip to main content

DbContext

Struct DbContext 

Source
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

Source

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 DbContextOptionsinventory::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.

Source

pub fn set<T>(&mut self) -> &mut DbSet<T>

Source

pub fn model(&mut self) -> &mut ModelBuilder

Returns the model builder for Fluent API configuration.

Source

pub fn model_builder(&self) -> &ModelBuilder

Returns a read-only reference to the model builder.

Source

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.

Source

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.

Source

pub fn detect_changes(&mut self)

Detects changes on all tracked DbSets by comparing property snapshots.

Source

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.

Source

pub async fn ensure_deleted(&self) -> EFResult<()>

Drops all tables for registered entity types.

Source§

impl DbContext

Source

pub fn provider(&self) -> &dyn IDatabaseProvider

Returns the database provider.

Source

pub fn change_tracker(&self) -> &ChangeTracker

Returns a read-only reference to the change tracker.

Source

pub fn change_tracker_mut(&mut self) -> &mut ChangeTracker

Returns a mutable reference to the change tracker.

Source

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?;
Source

pub fn transaction_mut(&mut self) -> Option<&mut Box<dyn ITransaction>>

Returns a mutable reference to the ambient transaction handle, if one is active (registered by use_transaction()).

Inside a use_transaction() closure, use this to access the ambient handle for savepoint and isolation operations. The borrow must be released (by scoping) before calling save_changes() or other &mut self methods.

Source

pub async fn begin_transaction(&mut self) -> EFResult<Box<dyn ITransaction>>

Begins a transaction and returns a typed handle.

The returned ITransaction handle is not registered as ambient — save_changes() calls will continue to self-manage their own transactions. Use this when you need explicit control via txn.commit() / txn.rollback() / txn.create_point() etc.

For scoped ambient transactions where save_changes() should reuse the same transaction, use DbContext::use_transaction instead.

commit / rollback consume the handle by value, preventing use-after-commit at the type level.

Source

pub async fn use_transaction<F, R>(&mut self, f: F) -> EFResult<R>
where for<'a> F: FnOnce(&'a mut Self) -> Pin<Box<dyn Future<Output = EFResult<R>> + Send + 'a>>, R: Send + 'static,

Executes a closure within an ambient transaction.

Registers the transaction as ambient for the duration of f, so that save_changes() calls inside f reuse the same transaction. Commits on Ok, rolls back on Err.

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.set::<Blog>().add(blog);
    ctx.save_changes().await?;
    Ok(())
})).await?;
Source§

impl DbContext

Source

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.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.