linq2db.EntityFrameworkCore 9.7.0

Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
dotnet add package linq2db.EntityFrameworkCore --version 9.7.0
                    
NuGet\Install-Package linq2db.EntityFrameworkCore -Version 9.7.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="linq2db.EntityFrameworkCore" Version="9.7.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="linq2db.EntityFrameworkCore" Version="9.7.0" />
                    
Directory.Packages.props
<PackageReference Include="linq2db.EntityFrameworkCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add linq2db.EntityFrameworkCore --version 9.7.0
                    
#r "nuget: linq2db.EntityFrameworkCore, 9.7.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package linq2db.EntityFrameworkCore@9.7.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=linq2db.EntityFrameworkCore&version=9.7.0
                    
Install as a Cake Addin
#tool nuget:?package=linq2db.EntityFrameworkCore&version=9.7.0
                    
Install as a Cake Tool

linq2db.EntityFrameworkCore

linq2db.EntityFrameworkCore is an integration of LINQ To DB with existing EntityFrameworkCore projects. It was inspired by this issue in EF.Core repository.

Unique features

  • Fast eager loading (incomparable faster on massive Include query)
  • Global query filters optimization
  • Better SQL optimization
  • CTE support
  • MERGE support
  • Table hints
  • Analytic/Window functions support
  • Fast BulkCopy of millions records
  • Native SQL operations for updating, deleting, inserting records via LINQ query
  • Temporary tables support
  • Cross database/linked server queries.
  • Full-Text search extensions
  • A lot of extensions to cover ANSI SQL

How to use

In your code you need to initialize integration using following call:

LinqToDBForEFTools.Initialize();

After that you can just call DbContext and IQueryable extension methods, provided by LINQ To DB.

You can also register additional options like interceptors for LinqToDB during EF context registration, here is an example:

var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
optionsBuilder.UseOracle(connectionString);
optionsBuilder.UseLinqToDB(builder =>
{
    // add custom command interceptor
    builder.AddInterceptor(new MyCommandInterceptor());
    // add additional mappings
    builder.AddMappingSchema(myCustomMappings);
    // configure provider-specific options
    builder.AddCustomOptions(o => o.WithOptions<OracleOptions>(oo => oo with
    {
        AlternativeBulkCopy = AlternativeBulkCopy.InsertInto
    }));
});

Configuring provider-specific options

AddCustomOptions receives an empty DataOptions instance. Connection string, connection and data provider are not part of it: they are taken from the EF Core context later, when a LINQ To DB context is created for it. This matters when you pick the method to configure a provider with:

  • use WithOptions<TOptions> to change provider behavior (bulk copy mode, identifier quoting, and so on). It updates only the corresponding option record and leaves connection and provider detection to the EF Core integration - this is what you want in almost all cases:

    builder.AddCustomOptions(o => o.WithOptions<OracleOptions>(oo => oo with
    {
        AlternativeBulkCopy = AlternativeBulkCopy.InsertInto
    }));
    
  • UseSqlServer, UseOracle, UseMySql and other UseXxx methods do more than that: they resolve a concrete IDataProvider instance and pin it on the options. A pinned provider takes precedence over the provider detected from the EF Core context, so use these methods only when you deliberately want to override that detection, e.g. to force a dialect:

    // force SQL Server 2022 dialect instead of detecting it from the server
    builder.AddCustomOptions(o => o.UseSqlServer(SqlServerVersion.v2022));
    
  • UseXxx overloads that leave the dialect at AutoDetect - including short ones such as UseOracle(optionSetter) - need to connect to the server to read its version. There is no connection string on the options at this point, so such a call fails with Connection string is not provided.. Pass an explicit dialect version, or configure the options with WithOptions<TOptions> instead.

There are many extensions for CRUD Operations missing in vanilla EF (watch our video):

// fast insert of big recordsets
ctx.BulkCopy(new BulkCopyOptions {...}, items);

// query for retrieving products that do not have duplicates by Name
var query =
    from p in ctx.Products
    from op in ctx.Products.LeftJoin(op => op.ProductID != p.ProductID && op.Name == p.Name)
    where Sql.ToNullable(op.ProductID) == null
    select p;

// insert these records into the same or another table
query.Insert(ctx.Products.ToLinqToDBTable(), s => new Product { Name = s.Name ... });

// update these records by changing name based on previous value
query.Update(prev => new Product { Name = "U_" + prev.Name ... });

// delete records that matched by query
query.Delete();

Some extensions require LINQ To DB ITable<T> interface, which could be acquired from DbSet<T> using ToLinqToDBTable() extension method.

For ITable<T> interface LINQ To DB provides several extensions that may be useful for complex databases and custom queries:

table = table.TableName("NewTableName");     // change table name in query
table = table.DatabaseName("OtherDatabase"); // change database name, useful for cross database queries.
table = table.OwnerName("OtherOwner");       // change owner.

// inserting into other existing table Products2
query.Insert(ctx.Products.ToLinqToDBTable().TableName("Products2"), s => new Product { Name = s.Name ... });

It is not required to work directly with LINQ To DB's DataConnection class but there are several ways to do that. LINQ To DB will try to reuse your configuration and select appropriate data provider:

// using DbContext
using (var dc = ctx.CreateLinqToDBConnection())
{
   // linq queries using linq2db extensions
}

// using DbContextOptions
using (var dc = options.CreateLinqToDBConnection())
{
   // linq queries using linq2db extensions
}

You can use all LINQ To DB extension functions in your EF linq queries. Just ensure you have called ToLinqToDB() function before materializing objects for synchronous methods.

Since EF Core have defined it's own asynchronous methods, we have to duplicate them to resolve naming collisions. Async methods have the same name but with LinqToDB suffix. E.g. ToListAsyncLinqToDB(), SumAsyncLinqToDB(), etc. The same methods are added when you need EF Core query processing but there is collision with LINQ To DB and they have extensions with EF suffix - ToListAsyncEF(), SumAsyncEF(), etc.

using (var ctx = CreateAdventureWorksContext())
{
    var productsWithModelCount =
        from p in ctx.Products
        select new
        {
            // Window Function
            Count = Sql.Ext.Count().Over().PartitionBy(p.ProductModelID).ToValue(),
            Product = p
        };

    var neededRecords =
        from p in productsWithModelCount
        where p.Count.Between(2, 4) // LINQ To DB extension
        select new
        {
            p.Product.Name,
            p.Product.Color,
            p.Product.Size,
            // retrieving value from column dynamically
            PhotoFileName = Sql.Property<string>(p.Product, "ThumbnailPhotoFileName")
        };

    // ensure we have replaced EF context
    var items1 = neededRecords.ToLinqToDB().ToArray();       
    
    // async version
    var items2 = await neededRecords.ToLinqToDB().ToArrayAsync(); 
    
    // and simple bonus - how to generate SQL
    var command = neededRecords.ToLinqToDB().ToSqlQuery();
}

Also check existing tests in test project for some examples.

Why should I want to use it?

There are many reasons. Some of them:

  • You want to use advanced SQL functionality, not supported or poorly supported by EntityFrameworkCore like BulkCopy support, SQL MERGE operations, convenient DML (Insert/Delete/Update) operations and many-many-many other features LINQ To DB provides, but you need change tracking functionality that EntityFramework provides.
  • You want to migrate to LINQ To DB, but need to do it step-by-step.
  • Just because LINQ To DB is cool.

Current status

Below is a list of providers, that should work right now:

  • SQL Server
  • MySQL (including Devart, Pomelo and Microting providers)
  • PostgreSQL (Both npgsql and Devart providers)
  • SQLite (including Devart provider)
  • Firebird
  • DB2 LUW
  • Oracle
  • SQL Server CE

Known limitations

  • No Lazy loading
  • No way to work with in-memory database
  • No TPT (table per type) support
  • No many-to-many support

Help! It doesn't work!

If you encounter any issue with this library, first check issues to see if it was already reported and if not, feel free to report new issue.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (9)

Showing the top 5 NuGet packages that depend on linq2db.EntityFrameworkCore:

Package Downloads
SimpleIdServer.Scim.Persistence.EF

EntityFramework persistence layer for SCIM2.0.

fbognini.Infrastructure

Persistence, multitenancy and repository implementations for fbognini projects.

Laraue.Core.DataAccess.Linq2DB

Extensions for Linq2DB database provider to work through EFCore context.

DALQueryChain.EntityFramework

Query Chain for Data Access Layer built on the Entity Framework ORM, allowing you to proxy queries to the DAL and use triggers

Dao.LightFramework

Package Description

GitHub repositories (7)

Showing the top 7 popular GitHub repositories that depend on linq2db.EntityFrameworkCore:

Repository Stars
bitwarden/server
Bitwarden infrastructure/backend (API, database, Docker, etc).
simpleidserver/SimpleIdServer
OpenID, OAuth 2.0, SCIM2.0, UMA2.0, FAPI, CIBA & OPENBANKING Framework for ASP.NET Core
HandyOrg/HandyWinGet
GUI for installing apps through WinGet and Creating Yaml file
SapiensAnatis/Dawnshard
Server emulator for Dragalia Lost
PhenX/PhenX.EntityFrameworkCore.BulkInsert
Super fast bulk insertion for Entity Framework Core on SQL Server, PostgreSQL, Sqlite, MySQL and Oracle
win7user10/Laraue.EfCoreTriggers
Library to write triggers in C# with EFCore
Adnatull/.NET-Clean-Architecture
Clean Architecture in ASP.Net 9.0. This contains Onion/Hexagonal architecture, DDD, CQRS using mediaTr, Unit Testing, Functional Testing, ASP.NET Core Identity, Entity Framework Core - Code First, Linq2db, Repository Pattern - Generic, Swagger UI, Response Wrappers, API Versioning, Automapper, Serilog, Exception handling, and so on.
Version Downloads Last Updated
10.6.0 854 9/11/2026
10.5.0 32,394 8/7/2026
10.4.0 162,327 5/17/2026
10.3.0 139,341 3/17/2026
10.2.0 9,201 3/12/2026
9.7.0 213 9/11/2026
9.6.0 1,871 8/7/2026
9.5.0 5,983 5/17/2026
9.4.0 8,376 3/17/2026
9.3.0 918 3/12/2026
8.8.0 56 9/11/2026
8.7.0 355 8/7/2026
8.6.0 4,663 5/17/2026
8.5.0 7,106 3/17/2026
8.4.0 710 3/12/2026
3.34.0 46 9/11/2026
3.33.0 125 8/7/2026
3.32.0 150 5/17/2026
3.31.0 623 3/17/2026
3.30.0 603 3/12/2026
Loading failed