Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversHalloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
FREEDOM251

Freedom251 › Blog › bulk operations

Entity Framework Extensions Settings: Match Controls to Each Operation

By Freedom251 Team · · 9 min read

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Entity Framework Extensions (EF Extensions) exposes hundreds of settings, but you normally supply them in one of three places: an operation lambda, a reusable typed options object, or the global EntityFrameworkManager.BulkOperationBuilder. Those settings control batching, timeouts, column and key selection, graph traversal, identity handling, merge behavior, auditing, logging, SQL hints, locking, and rows-affected results. The correct setting depends on the operation (such as bulk insert, update, merge, or BulkSaveChanges), the entity graph, your EF Extensions version, and the database provider.

This guide maps the option families, shows the supported configuration patterns, and explains the trade-offs that matter in production. The documentation describes broad capabilities rather than one permanent list: option names and support can change, so verify each setting against the package version and provider used by your application.

As an Amazon Associate I earn from qualifying purchases.

Where EF Extensions options are applied

Every bulk operation accepts configuration at call time. This is the safest place for a one-off exception, such as using a smaller batch for a very wide table or selecting a special key for one import. The fluent API accepts a lambda; a single assignment can be an expression-bodied lambda, while several assignments are clearer in a code block.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
context.BulkInsert(customers, options =>
{
    options.BatchSize = 1000;
    options.BatchTimeout = 60;
    options.ColumnPrimaryKeyExpression = customer => customer.ID;
});

The same options can be prepared once and reused. The options guide documents passing a BulkOperationOptions instance, including one created from a DbSet or DbContext; that form is available starting in v8.101.0. A typed object is useful when several jobs must use exactly the same column, timeout, and batching rules.

var options = context.CreateBulkOptions<Customer>();
options.BatchSize = 1000;
options.BatchTimeout = 60;
options.ColumnPrimaryKeyExpression = customer => customer.ID;

context.BulkInsert(customers, options);

For application-wide defaults, assign an EntityFrameworkManager.BulkOperationBuilder. Configure all intended defaults in that assignment. A later assignment replaces the previous builder rather than merging with it; splitting defaults across separate assignments can silently discard earlier settings.

EntityFrameworkManager.BulkOperationBuilder = builder =>
{
    builder.BatchSize = 5000;
    builder.BatchTimeout = 120;
};

Use the global builder for policies that should be consistent across operations, reusable options for a bounded set of jobs, and inline lambdas when the rule is local to one call. The processing model is the same; the choice mainly affects scope, readability, and the risk of an unintended global side effect.

Configuration style Best use Main caution
Inline lambda One operation or an intentional exception Rules can be duplicated across call sites
Reusable BulkOperationOptions Several operations sharing a typed policy Do not reuse settings that are specific to a different entity or operation
Global BulkOperationBuilder Organization-wide defaults A later builder assignment replaces the previous builder

Batching and execution controls

Batch options determine how many rows are sent together, how long a batch may wait, and whether EF Extensions pauses between batches. They influence round trips, memory consumption, lock duration, and timeout behavior; there is no universally optimal value.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

BatchSize: rows per batch

BatchSize sets the number of rows in each batch. A value of zero delegates selection to the provider and operation. ZZZ Projects’ batch-options documentation, last updated 2025-08-19, lists these documented defaults:

Provider Documented default when set to 0 Qualification
SQL Server 10,000 Vendor-documented provider default
PostgreSQL 10,000 Vendor-documented provider default
MySQL 200 Vendor-documented provider default
MariaDB 200 Vendor-documented provider default
SQLite 1 Vendor-documented provider default
Firebird 125 Vendor-documented provider default
Oracle 2,000 for insert/delete; 200 for update/merge Operation-specific provider default
InMemory and Effort int.MaxValue Vendor-documented provider default

Treat those figures as documentation defaults for the relevant library version, not as a promise of best performance. Smaller batches can increase round trips and command overhead. Larger batches may require more memory and take longer to complete, increasing the chance that a command reaches its timeout. The practical result also depends on row and column width, indexes, triggers, network latency, and server speed.

Benchmark representative data in the target environment. Start with the provider’s documented behavior, then compare a few nearby values while measuring elapsed time, memory, lock waits, and failure recovery. A value that wins for inserts may be poor for updates or merges.

BatchTimeout: maximum wait for one batch

BatchTimeout limits how long a batch may wait. When the EF context command timeout is specified, the guide states that it is the default for this option. Set a larger value only when the workload legitimately needs it; increasing the timeout can hide an inefficient query or an unexpected lock.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

BatchDelayInterval: pause between batches

BatchDelayInterval is a delay in milliseconds between batches and defaults to zero. A delay can reduce pressure on a busy server, but the documentation discourages using it inside a transaction. Every pause keeps the transaction open, which can extend lock duration and increase deadlock, concurrency, and reliability problems. If throttling is necessary, test it with the same transaction boundaries and contention patterns used in production.

Columns, keys, and operation-specific behavior

Many selectors accept either a strongly typed expression or a list of property names. An expression is concise and checked by the compiler:

options.ColumnPrimaryKeyExpression = item => item.ID;

For a composite key, use an anonymous object expression:

options.ColumnPrimaryKeyExpression = item => new
{
    item.TenantId,
    item.ExternalCode
};

When property names come from configuration or metadata at runtime, use the corresponding List<string> property:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
options.ColumnPrimaryKeyNames = new List<string>
{
    "TenantId",
    "ExternalCode"
};

The same expression-or-name pattern appears across many column-related options. Do not assume that a selector has identical meaning for every operation. Insert, update, merge, ignore, and output-column settings are interpreted in the context of the operation being executed. For example, a column that should be omitted during insert may be required for an update match, and output columns matter only when values are returned to the entities.

Identity and generated values

Operation pages document controls for identity handling and generated values. Whether an identity column is inserted explicitly, generated by the database, or returned after the operation is provider- and operation-dependent. Confirm the relevant insert, merge, or update documentation before changing identity behavior, especially when importing records that already have keys.

Ignored and output columns

Ignore-column settings prevent selected properties from participating in a specific operation. Output-column settings determine which database-generated values are copied back. Configure these per operation rather than treating an ignore list as a universal entity rule; a property ignored during insert may still be needed during update or merge.

Merge rules and matching keys

Merge operations combine insert and update behavior. Their key selectors determine how an incoming row matches an existing row, while insert and update column lists determine which values are written in each branch. Composite keys should be expressed explicitly so that a partial match cannot update the wrong tenant or record.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Related entities with IncludeGraph

Set IncludeGraph when a bulk insert, update, or merge must traverse related entities. The graph operation can process parent and child entities, but not every option is copied in the same way. Settings such as BatchSize can flow through the graph, while column settings depend on the entity type.

Configure per-entity column behavior through IncludeGraphOperationBuilder. This is where you specify different key, insert, update, or ignore columns for a parent and its children. A single root-level column expression cannot safely describe every type in a heterogeneous graph.

The graph documentation also describes read-only per-entity handling and situations that require a context factory. If a graph operation creates or accesses contexts during traversal, provide the factory pattern required by your version and hosting model rather than assuming the original context will always be reused.

Lazy navigation loading

For EF Core, LoadLazyNavigations is documented beginning in v10.5.7 and applies to EF Core 3.0 or later. Enabling it allows lazy navigations to be loaded before graph traversal. By default, EF Extensions traverses navigations that are already loaded; unloaded non-lazy navigations remain skipped even when this setting exists. This distinction matters when a relationship was not included in the query and has no lazy-loading proxy.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Because graph behavior is version-sensitive, check both the EF Core version and the EF Extensions package version before relying on this setting. Loading additional relationships can also increase queries and memory use, so scope the graph deliberately.

Other behavior families you can configure

The operation-specific documentation describes option families beyond batching and columns. Availability and exact names vary by operation and provider.

Behavior family What it changes Questions to answer first
Identity handling Whether generated or supplied identity values are used and returned Are keys database-generated, imported, or composite?
Ignored columns Properties excluded from a particular write operation Should the property be ignored only for insert, or also for update/merge?
Insert/update merge rules Which columns are written in each branch and how matches are found What uniquely identifies a row, and should nulls overwrite existing values?
Audit capture Collection of information about rows or changes during the operation Which audit data is required, and what is the provider’s support?
Logging Diagnostic output for generated commands and execution Can sensitive values appear in logs, and where should logs be routed?
SQL hints Provider-specific directives that influence execution plans or locking Does the target provider support the hint, and is it still valid after upgrades?
Table locking Lock strategy used while processing a table Can readers and writers tolerate the resulting blocking?
Rows-affected results How affected-row counts are reported Does the application need counts for validation or retry decisions?

These are not interchangeable global switches. A hint meaningful on SQL Server may be unsupported elsewhere, and a rows-affected result available for one operation may not have the same semantics for a graph or merge. Read the page for the exact operation and provider before standardizing any of them.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

BulkSaveChanges options and expectations

BulkSaveChanges processes tracked entities in Added, Modified, or Deleted states using bulk operations. It supports an options overload, so you can apply settings such as BatchSize while retaining change-tracker-driven behavior.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
context.BulkSaveChanges(options =>
{
    options.BatchSize = 2000;
});

The page describes related-entity and mapping capabilities, but performance claims need careful qualification. ZZZ Projects’ page, last updated 2026-08-18, publishes this comparison:

Best Value
Sale
Programming Entity Framework
  • Used Book in Good Condition
Entities SaveChanges BulkSaveChanges
1,000 1,200 ms 150 ms
2,000 2,400 ms 225 ms
5,000 6,000 ms 500 ms

These are vendor-published comparison figures, not an independent benchmark. They do not predict your provider, schema, triggers, indexes, network, or transaction profile. Measure your own tracked-entity workload before using them to set a service-level target.

A practical method for choosing options

  1. Identify the operation. Start with bulk insert, update, delete, merge, graph work, or BulkSaveChanges. The operation determines which columns and behavior controls are meaningful.
  2. Identify the provider and package version. Record the database provider, EF Core or EF6 target, and installed EF Extensions version. Defaults and feature availability are not universal.
  3. Define matching and generated-value rules. Decide the primary or composite key, identity behavior, ignored columns, and output columns before tuning performance.
  4. Choose configuration scope. Keep exceptions inline, share a typed options object among related jobs, and place only stable policies in the global builder.
  5. Set a safe batch baseline. Use provider defaults or a conservative explicit size, then measure round trips, memory, lock waits, and timeout frequency.
  6. Add graph rules per entity. If IncludeGraph is enabled, configure child-specific columns through IncludeGraphOperationBuilder and decide whether lazy navigations should load.
  7. Validate under production-like contention. Test triggers, indexes, concurrent readers and writers, transaction boundaries, and rollback behavior. A faster isolated run can be less reliable in a busy system.

Common failure modes and fixes

A global setting appears to disappear

Check for multiple assignments to EntityFrameworkManager.BulkOperationBuilder. The last assignment replaces the previous builder. Consolidate related defaults into one assignment or use a reusable options object.

A graph writes parent rows but not children

Verify IncludeGraph, confirm that the navigation is loaded or eligible for lazy loading, and inspect per-entity rules in IncludeGraphOperationBuilder. Unloaded non-lazy navigations are skipped.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A composite key matches the wrong row

Use an anonymous-object key expression or a complete List<string> of key names. Ensure every tenant or partition component is included in the match.

Batches time out or consume excessive memory

Reduce BatchSize, check row width and index maintenance, and measure server waits. Increase BatchTimeout only after determining that the work is legitimate rather than blocked or inefficient.

Adding a delay causes blocking

Remove or reduce BatchDelayInterval inside transactions. The pause extends transaction lifetime and can worsen lock and deadlock behavior.

Version and provider checklist

  • Confirm option names and support in the EF Extensions documentation matching the installed package.
  • Check whether the setting applies to EF Core, EF6, or both.
  • For graph loading, verify the EF Core 3.0-or-later requirement and the LoadLazyNavigations availability documented from v10.5.7.
  • Validate provider-specific batch defaults rather than copying SQL Server values to another database.
  • Test operation-specific column, identity, merge, hint, locking, audit, logging, and rows-affected behavior after upgrades.
  • Keep global defaults minimal; put entity- or operation-specific rules closer to the call that needs them.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

bulk operationsBulkSaveChangesC++EF CoreEntity Framework ExtensionsIncludeGraph

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.