├── .editorconfig ├── .gitignore ├── Build ├── SetVersion.ps1 └── linq2db.snk ├── Directory.Build.props ├── Directory.Packages.props ├── MIT-LICENSE.txt ├── NuGet.config ├── NuGet ├── BuildNuspecs.ps1 ├── icon.png └── linq2db.EntityFrameworkCore.nuspec ├── README.md ├── Source ├── .editorconfig └── LinqToDB.EntityFrameworkCore │ ├── EFConnectionInfo.cs │ ├── EFCoreMetadataReader.cs │ ├── EFProviderInfo.cs │ ├── ILinqToDBForEFTools.cs │ ├── Internal │ ├── EFCoreExpressionAttribute.cs │ ├── LinqToDBForEFQueryProvider.cs │ └── LinqToDBOptionsExtension.cs │ ├── LinqToDBContextOptionsBuilder.cs │ ├── LinqToDBExtensionsAdapter.cs │ ├── LinqToDBForEFExtensions.Async.EF.cs │ ├── LinqToDBForEFExtensions.Async.cs │ ├── LinqToDBForEFTools.ContextExtensions.cs │ ├── LinqToDBForEFTools.ContextOptionsBuilderExtensions.cs │ ├── LinqToDBForEFTools.Extensions.cs │ ├── LinqToDBForEFTools.Mapping.cs │ ├── LinqToDBForEFTools.cs │ ├── LinqToDBForEFToolsDataConnection.cs │ ├── LinqToDBForEFToolsDataContext.cs │ ├── LinqToDBForEFToolsException.cs │ ├── LinqToDBForEFToolsImplDefault.cs │ ├── LinqToDBProviderInfo.cs │ ├── Properties │ ├── AssemblyInfo.cs │ └── JetBrains.Annotations.cs │ └── linq2db.EntityFrameworkCore.csproj ├── Tests ├── .editorconfig ├── Directory.Build.props ├── LinqToDB.EntityFrameworkCore.BaseTests │ ├── ForMappingTestsBase.cs │ ├── Interceptors │ │ ├── Extensions │ │ │ └── LinqToDBContextOptionsBuilderExtensions.cs │ │ ├── TestCommandInterceptor.cs │ │ ├── TestConnectionInterceptor.cs │ │ ├── TestDataContextInterceptor.cs │ │ ├── TestEfCoreAndLinqToDBComboInterceptor.cs │ │ ├── TestEntityServiceInterceptor.cs │ │ └── TestInterceptor.cs │ ├── LinqToDB.EntityFrameworkCore.BaseTests.csproj │ ├── Logging │ │ ├── LogMessageEntry.cs │ │ ├── NullExternalScopeProvider.cs │ │ ├── NullScope.cs │ │ ├── TestLogger.cs │ │ ├── TestLoggerExtensions.cs │ │ └── TestLoggerProvider.cs │ ├── Models │ │ ├── ForMapping │ │ │ ├── ForMappingContextBase.cs │ │ │ ├── NoIdentity.cs │ │ │ ├── StringTypes.cs │ │ │ ├── TypesTable.cs │ │ │ ├── UIntTable.cs │ │ │ ├── WithDuplicateProperties.cs │ │ │ ├── WithIdentity.cs │ │ │ └── WithInheritance.cs │ │ └── Northwind │ │ │ ├── BaseEntity.cs │ │ │ ├── Category.cs │ │ │ ├── Customer.cs │ │ │ ├── CustomerCustomerDemo.cs │ │ │ ├── CustomerDemographics.cs │ │ │ ├── CustomerOrderHistory.cs │ │ │ ├── CustomerQuery.cs │ │ │ ├── CustomerView.cs │ │ │ ├── Employee.cs │ │ │ ├── EmployeeTerritory.cs │ │ │ ├── NorthwindData.Objects.cs │ │ │ ├── NorthwindData.cs │ │ │ ├── Order.cs │ │ │ ├── OrderDetail.cs │ │ │ ├── Product.cs │ │ │ ├── Region.cs │ │ │ ├── Shipper.cs │ │ │ ├── Supplier.cs │ │ │ └── Territory.cs │ ├── TestUtils.cs │ └── TestsBase.cs ├── LinqToDB.EntityFrameworkCore.FSharpTests │ ├── LinqToDB.EntityFrameworkCore.FSharpTests.fsproj │ └── Tests.fs ├── LinqToDB.EntityFrameworkCore.PomeloMySql.Tests │ ├── ForMappingTests.cs │ ├── LinqToDB.EntityFrameworkCore.PomeloMySql.Tests.csproj │ ├── Models │ │ ├── ForMapping │ │ │ └── ForMappingContext.cs │ │ ├── Northwind.Mapping │ │ │ ├── CategoriesMap.cs │ │ │ ├── CustomerCustomerDemoMap.cs │ │ │ ├── CustomerDemographicsMap.cs │ │ │ ├── CustomersMap.cs │ │ │ ├── EmployeeTerritoriesMap.cs │ │ │ ├── EmployeesMap.cs │ │ │ ├── OrderDetailsMap.cs │ │ │ ├── OrderMap.cs │ │ │ ├── ProductsMap.cs │ │ │ ├── RegionMap.cs │ │ │ ├── ShippersMap.cs │ │ │ ├── SuppliersMap.cs │ │ │ └── TerritoriesMap.cs │ │ └── Northwind │ │ │ └── NorthwindContext.cs │ └── PomeloMySqlTests.cs ├── LinqToDB.EntityFrameworkCore.PostgreSQL.Tests │ ├── ForMappingTests.cs │ ├── LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.csproj │ ├── Models │ │ ├── ForMapping │ │ │ └── ForMappingContext.cs │ │ └── NpgSqlEntities │ │ │ ├── EntityWithArrays.cs │ │ │ ├── EntityWithXmin.cs │ │ │ ├── Event.cs │ │ │ ├── EventView.cs │ │ │ ├── NpgSqlEntitiesContext.cs │ │ │ └── TimeStampEntity.cs │ ├── NpgSqlTests.cs │ └── SampleTests │ │ ├── AAA.cs │ │ ├── Child.cs │ │ ├── DataContextExtensions.cs │ │ ├── Detail.cs │ │ ├── Entity.cs │ │ ├── Entity2Item.cs │ │ ├── IHasId.cs │ │ ├── Id.cs │ │ ├── IdTests.cs │ │ ├── IdValueConverter.cs │ │ ├── Item.cs │ │ ├── ModelBuilderExtensions.cs │ │ ├── QueryableExtensions.cs │ │ ├── StringExtensions.cs │ │ ├── SubDetail.cs │ │ └── TypeExtensions.cs ├── LinqToDB.EntityFrameworkCore.SQLite.Tests │ ├── ForMappingTests.cs │ ├── InterceptorTests.cs │ ├── LinqToDB.EntityFrameworkCore.SQLite.Tests.csproj │ ├── Models │ │ ├── ForMapping │ │ │ └── ForMappingContext.cs │ │ ├── Northwind.Mapping │ │ │ ├── CategoriesMap.cs │ │ │ ├── CustomerCustomerDemoMap.cs │ │ │ ├── CustomerDemographicsMap.cs │ │ │ ├── CustomersMap.cs │ │ │ ├── EmployeeTerritoriesMap.cs │ │ │ ├── EmployeesMap.cs │ │ │ ├── OrderDetailsMap.cs │ │ │ ├── OrderMap.cs │ │ │ ├── ProductsMap.cs │ │ │ ├── RegionMap.cs │ │ │ ├── ShippersMap.cs │ │ │ ├── SuppliersMap.cs │ │ │ └── TerritoriesMap.cs │ │ └── Northwind │ │ │ └── NorthwindContext.cs │ └── SQLiteTests.cs └── LinqToDB.EntityFrameworkCore.SqlServer.Tests │ ├── ForMappingTests.cs │ ├── IssueTests.cs │ ├── JsonConvertTests.cs │ ├── LinqToDB.EntityFrameworkCore.SqlServer.Tests.csproj │ ├── Models │ ├── ForMapping │ │ └── ForMappingContext.cs │ ├── Inheritance │ │ └── InheritanceContext.cs │ ├── IssueModel │ │ ├── Issue117Entities.cs │ │ ├── Issue73Entity.cs │ │ └── IssueContext.cs │ ├── Northwind.Mapping │ │ ├── BaseEntityMap.cs │ │ ├── CategoriesMap.cs │ │ ├── CustomerCustomerDemoMap.cs │ │ ├── CustomerDemographicsMap.cs │ │ ├── CustomersMap.cs │ │ ├── EmployeeTerritoriesMap.cs │ │ ├── EmployeesMap.cs │ │ ├── OrderDetailsMap.cs │ │ ├── OrderMap.cs │ │ ├── ProductsMap.cs │ │ ├── RegionMap.cs │ │ ├── ShippersMap.cs │ │ ├── SuppliersMap.cs │ │ └── TerritoriesMap.cs │ └── Northwind │ │ └── NorthwindContext.cs │ ├── Settings.cs │ ├── ToolsTests.cs │ └── ValueConversion │ ├── ConvertorTests.cs │ ├── IEntity`1.cs │ ├── IdValueConverterSelector.cs │ ├── IdValueConverter`2.cs │ ├── Id`2.cs │ └── SubDivision.cs ├── azure-pipelines.yml ├── linq2db.EFCore.sln ├── linq2db.EFCore.sln.DotSettings └── spellcheck.txt /.gitignore: -------------------------------------------------------------------------------- 1 | #Ignore files build by IDE 2 | *.user 3 | bin/ 4 | obj/ 5 | _ReSharper*/ 6 | /.vs/* 7 | /.tools/ 8 | /.idea/ 9 | -------------------------------------------------------------------------------- /Build/SetVersion.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | [Parameter(Mandatory=$true)][string]$path, 3 | [Parameter(Mandatory=$true)][string]$version 4 | ) 5 | 6 | $ErrorActionPreference = "Stop" 7 | Set-StrictMode -Version Latest 8 | 9 | if ($version) { 10 | 11 | $xmlPath = Resolve-Path "$path" 12 | 13 | $xml = [XML](Get-Content "$xmlPath") 14 | $xml.PreserveWhitespace = $true 15 | $save = $false 16 | 17 | $xPath = "//PropertyGroup/Version" 18 | $nodes = $xml.SelectNodes($xPath) 19 | foreach($node in $nodes) { 20 | $node.InnerXml = $version 21 | $save = $true 22 | } 23 | 24 | if ($save) { 25 | Write-Host "Patched $xmlPath" 26 | $xml.Save($xmlPath) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Build/linq2db.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linq2db/linq2db.EntityFrameworkCore/ad20a61cc1b82c9f861fa71590f4db423bf9c24d/Build/linq2db.snk -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 9.0.0 4 | 5 | Svyatoslav Danyliv, Igor Tkachev, Dmitry Lukashenko, Ilya Chudin 6 | Linq to DB 7 | linq2db.net 8 | 2002-2024 linq2db.net 9 | https://github.com/linq2db/linq2db.EntityFrameworkCore 10 | git 11 | 12 | latest 13 | enable 14 | 9999 15 | prompt 16 | strict 17 | True 18 | 19 | false 20 | false 21 | True 22 | ..\..\Build\linq2db.snk 23 | False 24 | 25 | true 26 | true 27 | true 28 | true 29 | true 30 | true 31 | false 32 | true 33 | 34 | true 35 | 36 | 37 | true 38 | 39 | true 40 | 41 | net8.0 42 | 43 | 44 | 45 | true 46 | true 47 | preview-All 48 | true 49 | true 50 | true 51 | 52 | 53 | -------------------------------------------------------------------------------- /Directory.Packages.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Igor Tkachev, Ilya Chudin, Svyatoslav Danyliv, Dmitry Lukashenko 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /NuGet.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /NuGet/BuildNuspecs.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | [Parameter(Mandatory=$true)][string]$path, 3 | [Parameter(Mandatory=$true)][string]$version, 4 | [Parameter(Mandatory=$false)][string]$branch 5 | ) 6 | 7 | $ErrorActionPreference = "Stop" 8 | Set-StrictMode -Version Latest 9 | 10 | if ($version) { 11 | 12 | $nsUri = 'http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd' 13 | $ns = @{ns=$nsUri} 14 | $commit = (git rev-parse HEAD) 15 | if (-not $branch) { 16 | $branch = (git rev-parse --abbrev-ref HEAD) 17 | } 18 | 19 | Get-ChildItem $path | ForEach { 20 | $xmlPath = Resolve-Path $_.FullName 21 | 22 | $xml = [xml] (Get-Content "$xmlPath") 23 | $xml.PreserveWhitespace = $true 24 | 25 | # set version metadata 26 | $child = $xml.CreateElement('version', $nsUri) 27 | $child.InnerText = $version 28 | $xml.package.metadata.AppendChild($child) 29 | 30 | # set repository/commit link 31 | $child = $xml.CreateElement('repository', $nsUri) 32 | $attr = $xml.CreateAttribute('type') 33 | $attr.Value = 'git' 34 | $child.Attributes.Append($attr) 35 | $attr = $xml.CreateAttribute('url') 36 | $attr.Value = 'https://github.com/linq2db/linq2db.EntityFrameworkCore.git' 37 | $child.Attributes.Append($attr) 38 | $attr = $xml.CreateAttribute('branch') 39 | $attr.Value = $branch 40 | $child.Attributes.Append($attr) 41 | $attr = $xml.CreateAttribute('commit') 42 | $attr.Value = $commit 43 | $child.Attributes.Append($attr) 44 | $xml.package.metadata.AppendChild($child) 45 | 46 | $xml.Save($xmlPath) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /NuGet/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linq2db/linq2db.EntityFrameworkCore/ad20a61cc1b82c9f861fa71590f4db423bf9c24d/NuGet/icon.png -------------------------------------------------------------------------------- /NuGet/linq2db.EntityFrameworkCore.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | linq2db.EntityFrameworkCore 5 | Linq to DB (linq2db) extensions for Entity Framework Core 6 | Igor Tkachev, Ilya Chudin, Svyatoslav Danyliv, Dmitry Lukashenko 7 | Igor Tkachev, Ilya Chudin, Svyatoslav Danyliv, Dmitry Lukashenko 8 | Copyright © 2020-2024 Igor Tkachev, Ilya Chudin, Svyatoslav Danyliv, Dmitry Lukashenko 9 | Allows to execute Linq to DB (linq2db) queries in Entity Framework Core DbContext. 10 | 11 | linq linq2db LinqToDB ORM database entity-framework-core EntityFrameworkCore EFCore DB SQL SqlServer SqlCe SqlServerCe MySql Firebird SQLite Oracle ODP PostgreSQL DB2 12 | false 13 | images\icon.png 14 | https://github.com/linq2db/linq2db.EntityFrameworkCore 15 | MIT-LICENSE.txt 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Source/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | dotnet_diagnostic.CA1827.severity = error # CA1827: Do not use Count/LongCount when Any can be used 3 | dotnet_diagnostic.CA2007.severity = error # CA2007: Do not directly await a Task 4 | dotnet_diagnostic.CA1829.severity = error # CA1829: Use Length/Count property instead of Enumerable.Count method 5 | -------------------------------------------------------------------------------- /Source/LinqToDB.EntityFrameworkCore/EFConnectionInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | 3 | namespace LinqToDB.EntityFrameworkCore 4 | { 5 | /// 6 | /// Contains database connectivity information, extracted from EF.Core. 7 | /// 8 | public sealed class EFConnectionInfo 9 | { 10 | /// 11 | /// Gets or sets database connection instance. 12 | /// 13 | public DbConnection? Connection { get; set; } 14 | 15 | /// 16 | /// Gets or sets database connection string. 17 | /// 18 | public string? ConnectionString { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Source/LinqToDB.EntityFrameworkCore/EFProviderInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Infrastructure; 5 | 6 | namespace LinqToDB.EntityFrameworkCore 7 | { 8 | /// 9 | /// Required integration information about underlying database provider, extracted from EF.Core. 10 | /// 11 | public sealed class EFProviderInfo 12 | { 13 | /// 14 | /// Gets or sets database connection instance. 15 | /// 16 | public DbConnection? Connection { get; set; } 17 | 18 | /// 19 | /// Gets or sets EF.Core context instance. 20 | /// 21 | public DbContext? Context { get; set; } 22 | 23 | /// 24 | /// Gets or sets EF.Core context options instance. 25 | /// 26 | public IDbContextOptions? Options { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Source/LinqToDB.EntityFrameworkCore/Internal/EFCoreExpressionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | using LinqToDB.Mapping; 7 | using LinqToDB.SqlQuery; 8 | 9 | namespace LinqToDB.EntityFrameworkCore.Internal 10 | { 11 | /// 12 | /// Maps Linq To DB expression. 13 | /// 14 | public sealed class EFCoreExpressionAttribute : Sql.ExpressionAttribute 15 | { 16 | /// 17 | /// Creates instance of expression mapper. 18 | /// 19 | /// Mapped expression. 20 | public EFCoreExpressionAttribute(string expression) : base(expression) 21 | { 22 | } 23 | 24 | /// 25 | public override ISqlExpression? GetExpression( 26 | TContext context, 27 | IDataContext dataContext, 28 | SelectQuery query, 29 | Expression expression, 30 | Func converter) 31 | { 32 | var knownExpressions = new List(); 33 | if (expression.NodeType == ExpressionType.Call) 34 | { 35 | var mc = (MethodCallExpression) expression; 36 | if (!mc.Method.IsStatic) 37 | knownExpressions.Add(mc.Object!); 38 | knownExpressions.AddRange(mc.Arguments); 39 | } 40 | else 41 | { 42 | var me = (MemberExpression) expression; 43 | knownExpressions.Add(me.Expression!); 44 | } 45 | 46 | var @params = new List(knownExpressions.Select(_ => (ISqlExpression?) null)); 47 | 48 | _ = ResolveExpressionValues((context, @params, knownExpressions, converter), Expression!, 49 | static (ctx, v, d) => 50 | { 51 | var idx = int.Parse(v, CultureInfo.InvariantCulture); 52 | 53 | if (ctx.@params[idx] == null) 54 | ctx.@params[idx] = ctx.converter(ctx.context, ctx.knownExpressions[idx], null); 55 | 56 | return v; 57 | }); 58 | 59 | var parameters = @params.Select(p => p ?? new SqlExpression("!!!")).ToArray(); 60 | return new SqlExpression(expression.Type, Expression!, Precedence, parameters); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Source/LinqToDB.EntityFrameworkCore/Internal/LinqToDBOptionsExtension.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | using Microsoft.EntityFrameworkCore.Infrastructure; 5 | using Microsoft.Extensions.DependencyInjection; 6 | 7 | namespace LinqToDB.EntityFrameworkCore.Internal 8 | { 9 | /// 10 | /// Model containing LinqToDB related context options. 11 | /// 12 | public class LinqToDBOptionsExtension : IDbContextOptionsExtension 13 | { 14 | private DbContextOptionsExtensionInfo? _info; 15 | 16 | /// 17 | /// Context options extension info object. 18 | /// 19 | public DbContextOptionsExtensionInfo Info 20 | => _info ??= new LinqToDBExtensionInfo(this); 21 | 22 | /// 23 | /// List of registered LinqToDB interceptors 24 | /// 25 | public virtual DataOptions Options { get; set; } 26 | 27 | /// 28 | /// .ctor 29 | /// 30 | public LinqToDBOptionsExtension() 31 | { 32 | Options = new(); 33 | } 34 | 35 | /// 36 | /// .ctor 37 | /// 38 | /// 39 | protected LinqToDBOptionsExtension(LinqToDBOptionsExtension copyFrom) 40 | { 41 | Options = copyFrom.Options; 42 | } 43 | 44 | /// Adds the services required to make the selected options work. This is used when 45 | /// there is no external System.IServiceProvider and EF is maintaining its own service 46 | /// provider internally. This allows database providers (and other extensions) to 47 | /// register their required services when EF is creating an service provider. 48 | /// The collection to add services to 49 | public void ApplyServices(IServiceCollection services) 50 | { 51 | ; 52 | } 53 | 54 | /// 55 | /// Gives the extension a chance to validate that all options in the extension are 56 | /// valid. Most extensions do not have invalid combinations and so this will be a 57 | /// no-op. If options are invalid, then an exception should be thrown. 58 | /// 59 | /// 60 | public void Validate(IDbContextOptions options) 61 | { 62 | ; 63 | } 64 | 65 | private sealed class LinqToDBExtensionInfo : DbContextOptionsExtensionInfo 66 | { 67 | private string? _logFragment; 68 | 69 | public LinqToDBExtensionInfo(IDbContextOptionsExtension extension) 70 | : base(extension) 71 | { 72 | } 73 | 74 | private new LinqToDBOptionsExtension Extension 75 | => (LinqToDBOptionsExtension)base.Extension; 76 | 77 | public override bool IsDatabaseProvider 78 | => false; 79 | 80 | public override string LogFragment 81 | { 82 | get 83 | { 84 | if (_logFragment == null) 85 | { 86 | string logFragment = string.Empty; 87 | 88 | if (Extension.Options.DataContextOptions.Interceptors?.Any() == true) 89 | { 90 | logFragment += $"Interceptors count: {Extension.Options.DataContextOptions.Interceptors.Count}"; 91 | } 92 | 93 | _logFragment = logFragment; 94 | } 95 | 96 | return _logFragment; 97 | } 98 | } 99 | 100 | public override int GetServiceProviderHashCode() => 0; 101 | 102 | public override void PopulateDebugInfo(IDictionary debugInfo) 103 | => debugInfo["LinqToDB"] = "1"; 104 | 105 | public override bool ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo other) => true; 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /Source/LinqToDB.EntityFrameworkCore/LinqToDBContextOptionsBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace LinqToDB.EntityFrameworkCore 5 | { 6 | using Interceptors; 7 | using Internal; 8 | using Mapping; 9 | 10 | /// 11 | /// Linq To DB context options builder 12 | /// 13 | public class LinqToDBContextOptionsBuilder 14 | { 15 | private readonly LinqToDBOptionsExtension? _extension; 16 | 17 | /// 18 | /// Db context options. 19 | /// 20 | public DbContextOptions DbContextOptions { get; private set; } 21 | 22 | /// 23 | /// .ctor 24 | /// 25 | /// 26 | public LinqToDBContextOptionsBuilder(DbContextOptionsBuilder optionsBuilder) 27 | { 28 | _extension = optionsBuilder.Options.FindExtension(); 29 | DbContextOptions = optionsBuilder.Options; 30 | } 31 | 32 | /// 33 | /// Registers Linq To DB interceptor. 34 | /// 35 | /// The interceptor instance to register. 36 | /// 37 | public LinqToDBContextOptionsBuilder AddInterceptor(IInterceptor interceptor) 38 | { 39 | if (_extension != null) 40 | _extension.Options = _extension.Options.UseInterceptor(interceptor); 41 | 42 | return this; 43 | } 44 | 45 | /// 46 | /// Registers custom Linq To DB MappingSchema. 47 | /// 48 | /// The interceptor instance to register. 49 | /// 50 | public LinqToDBContextOptionsBuilder AddMappingSchema(MappingSchema mappingSchema) 51 | { 52 | if (_extension != null) 53 | _extension.Options = _extension.Options.UseMappingSchema(mappingSchema); 54 | 55 | return this; 56 | } 57 | 58 | /// 59 | /// Registers custom Linq To DB options. 60 | /// 61 | /// Function to setup custom Linq To DB options. 62 | /// 63 | public LinqToDBContextOptionsBuilder AddCustomOptions(Func optionsSetter) 64 | { 65 | if (_extension != null) 66 | _extension.Options = optionsSetter(_extension.Options); 67 | 68 | return this; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.ContextOptionsBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | 5 | namespace LinqToDB.EntityFrameworkCore 6 | { 7 | using Internal; 8 | 9 | public static partial class LinqToDBForEFTools 10 | { 11 | /// 12 | /// Registers custom options related to LinqToDB provider. 13 | /// 14 | /// 15 | /// Custom options action. 16 | /// 17 | [Obsolete($"Use {nameof(UseLinqToDB)} overload.")] 18 | public static DbContextOptionsBuilder UseLinqToDb( 19 | this DbContextOptionsBuilder optionsBuilder, 20 | Action? linq2dbOptionsAction = null) 21 | => UseLinqToDB(optionsBuilder, linq2dbOptionsAction); 22 | 23 | /// 24 | /// Registers custom options related to LinqToDB provider. 25 | /// 26 | /// 27 | /// Custom options action. 28 | /// 29 | public static DbContextOptionsBuilder UseLinqToDB( 30 | this DbContextOptionsBuilder optionsBuilder, 31 | Action? linq2dbOptionsAction = null) 32 | { 33 | ((IDbContextOptionsBuilderInfrastructure)optionsBuilder) 34 | .AddOrUpdateExtension(GetOrCreateExtension(optionsBuilder)); 35 | 36 | linq2dbOptionsAction?.Invoke(new LinqToDBContextOptionsBuilder(optionsBuilder)); 37 | 38 | return optionsBuilder; 39 | } 40 | 41 | private static LinqToDBOptionsExtension GetOrCreateExtension(DbContextOptionsBuilder options) 42 | => options.Options.FindExtension() 43 | ?? new LinqToDBOptionsExtension(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.Extensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace LinqToDB.EntityFrameworkCore 4 | { 5 | public static partial class LinqToDBForEFTools 6 | { 7 | /// 8 | /// Converts EF.Core instance to LINQ To DB instance. 9 | /// 10 | /// Mapping entity type. 11 | /// EF.Core instance. 12 | /// LINQ To DB instance. 13 | public static ITable ToLinqToDBTable(this DbSet dbSet) 14 | where T : class 15 | { 16 | var context = Implementation.GetCurrentContext(dbSet) 17 | ?? throw new LinqToDBForEFToolsException($"Can not load current context from {nameof(dbSet)}"); 18 | #pragma warning disable CA2000 // Dispose objects before losing scope 19 | var dc = CreateLinqToDBContext(context); 20 | #pragma warning restore CA2000 // Dispose objects before losing scope 21 | return dc.GetTable(); 22 | } 23 | 24 | /// 25 | /// Converts EF.Core instance to LINQ To DB instance 26 | /// using existing LINQ To DB instance. 27 | /// 28 | /// Mapping entity type. 29 | /// EF.Core instance. 30 | /// LINQ To DB data context instance. 31 | /// LINQ To DB instance. 32 | public static ITable ToLinqToDBTable(this DbSet dbSet, IDataContext dataContext) 33 | where T : class 34 | { 35 | return dataContext.GetTable(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.Mapping.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | using System.Reflection; 5 | 6 | using Microsoft.EntityFrameworkCore; 7 | 8 | namespace LinqToDB.EntityFrameworkCore 9 | { 10 | using Expressions; 11 | using Extensions; 12 | 13 | public partial class LinqToDBForEFTools 14 | { 15 | static void InitializeMapping() 16 | { 17 | Linq.Expressions.MapMember( 18 | (DbFunctions f, string m, string p) => f.Like(m, p), (f, m, p) => Sql.Like(m, p)); 19 | 20 | // InitializeSqlServerMapping(); 21 | } 22 | 23 | 24 | #region Sql Server 25 | 26 | static Sql.DateParts? GetDatePart(string name) 27 | { 28 | return name switch 29 | { 30 | "Year" => (Sql.DateParts?)Sql.DateParts.Year, 31 | "Day" => (Sql.DateParts?)Sql.DateParts.Day, 32 | "Month" => (Sql.DateParts?)Sql.DateParts.Month, 33 | "Hour" => (Sql.DateParts?)Sql.DateParts.Hour, 34 | "Minute" => (Sql.DateParts?)Sql.DateParts.Minute, 35 | "Second" => (Sql.DateParts?)Sql.DateParts.Second, 36 | "Millisecond" => (Sql.DateParts?)Sql.DateParts.Millisecond, 37 | _ => null, 38 | }; 39 | } 40 | 41 | /// 42 | /// Initializes SQL Server's DbFunctions dynamically to avoid dependency 43 | /// 44 | static void InitializeSqlServerMapping() 45 | { 46 | var type = Type.GetType("Microsoft.EntityFrameworkCore.SqlServerDbFunctionsExtensions, Microsoft.EntityFrameworkCore.SqlServer", false); 47 | 48 | if (type == null) 49 | return; 50 | 51 | var sqlServerMethods = type.GetMethods(BindingFlags.Public | BindingFlags.Static) 52 | .Where(m => m.GetParameters().Length > 0) 53 | .ToArray(); 54 | 55 | var dbFunctionsParameter = Expression.Parameter(typeof(DateTime), "dbFunctions"); 56 | 57 | var dateDiffStr = "DateDiff"; 58 | var dateDiffMethods = sqlServerMethods.Where(m => m.Name.StartsWith(dateDiffStr)).ToArray(); 59 | 60 | var dateDiffMethod = MemberHelper.MethodOf(() => Sql.DateDiff(Sql.DateParts.Day, (DateTime?)null, null)); 61 | 62 | foreach (var method in dateDiffMethods) 63 | { 64 | var datePart = GetDatePart(method.Name.Substring(dateDiffStr.Length)); 65 | if (datePart == null) 66 | continue; 67 | 68 | var parameters = method.GetParameters(); 69 | if (parameters.Length < 3) 70 | continue; 71 | 72 | var boundaryType = parameters[1].ParameterType; 73 | if (boundaryType.ToUnderlying() != typeof(DateTime)) 74 | continue; 75 | 76 | var startParameter = Expression.Parameter(boundaryType, "start"); 77 | var endParameter = Expression.Parameter(boundaryType, "end"); 78 | 79 | var startExpr = startParameter.Type != typeof(DateTime?) 80 | ? (Expression) Expression.Convert(startParameter, typeof(DateTime?)) 81 | : startParameter; 82 | 83 | var endExpr = endParameter.Type != typeof(DateTime?) 84 | ? (Expression) Expression.Convert(endParameter, typeof(DateTime?)) 85 | : endParameter; 86 | 87 | 88 | var body = Expression.Call(dateDiffMethod, Expression.Constant(datePart.Value), startExpr, endExpr); 89 | var lambda = Expression.Lambda(body, dbFunctionsParameter, startParameter, endParameter); 90 | 91 | Linq.Expressions.MapMember(method, lambda); 92 | } 93 | } 94 | 95 | #endregion 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFToolsDataContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | 4 | using Microsoft.EntityFrameworkCore.Metadata; 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace LinqToDB.EntityFrameworkCore 8 | { 9 | 10 | using DataProvider; 11 | using Linq; 12 | 13 | /// 14 | /// Linq To DB EF.Core data context. 15 | /// 16 | public class LinqToDBForEFToolsDataContext : DataContext, IExpressionPreprocessor 17 | { 18 | readonly DbContext? _context; 19 | readonly IModel _model; 20 | readonly Func? _transformFunc; 21 | 22 | /// 23 | /// Creates instance of context. 24 | /// 25 | /// EF.Core database context. 26 | /// lin2db database provider instance. 27 | /// Connection string. 28 | /// EF.Core model. 29 | /// Expression converter. 30 | public LinqToDBForEFToolsDataContext( 31 | DbContext? context, 32 | IDataProvider dataProvider, 33 | string connectionString, 34 | IModel model, 35 | Func? transformFunc) : base(dataProvider, connectionString) 36 | { 37 | _context = context; 38 | _model = model; 39 | _transformFunc = transformFunc; 40 | } 41 | 42 | /// 43 | /// Converts expression using convert function, passed to context. 44 | /// 45 | /// Expression to convert. 46 | /// Converted expression. 47 | public Expression ProcessExpression(Expression expression) 48 | { 49 | if (_transformFunc == null) 50 | return expression; 51 | return _transformFunc(expression, this, _context, _model); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFToolsException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace LinqToDB.EntityFrameworkCore 4 | { 5 | /// 6 | /// Exception class for EF.Core to LINQ To DB integration issues. 7 | /// 8 | public sealed class LinqToDBForEFToolsException : Exception 9 | { 10 | /// 11 | /// Creates new instance of exception. 12 | /// 13 | public LinqToDBForEFToolsException() 14 | { 15 | } 16 | 17 | /// 18 | /// Creates new instance of exception. 19 | /// 20 | /// Exception message. 21 | public LinqToDBForEFToolsException(string message) : base(message) 22 | { 23 | } 24 | 25 | /// 26 | /// Creates new instance of exception when it generated for other exception. 27 | /// 28 | /// Exception message. 29 | /// Original exception. 30 | public LinqToDBForEFToolsException(string message, Exception innerException) : base(message, innerException) 31 | { 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Source/LinqToDB.EntityFrameworkCore/LinqToDBProviderInfo.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore 2 | { 3 | /// 4 | /// Stores LINQ To DB database provider information. 5 | /// 6 | public sealed class LinqToDBProviderInfo 7 | { 8 | /// 9 | /// Server version. Currently is not used. 10 | /// 11 | public string? Version { get; set; } 12 | 13 | /// 14 | /// Gets or sets LINQ To DB provider name. 15 | /// for available providers. 16 | /// 17 | public string? ProviderName { get; set; } 18 | 19 | /// 20 | /// Replaces null values in current instance with values from parameter. 21 | /// 22 | /// Provider information to merge into current object. 23 | public void Merge(LinqToDBProviderInfo? providerInfo) 24 | { 25 | if (providerInfo != null) 26 | { 27 | Version ??= providerInfo.Version; 28 | ProviderName ??= providerInfo.ProviderName; 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Source/LinqToDB.EntityFrameworkCore/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [module: SkipLocalsInit] 4 | -------------------------------------------------------------------------------- /Source/LinqToDB.EntityFrameworkCore/linq2db.EntityFrameworkCore.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Allows to execute Linq to DB (linq2db) queries in Entity Framework Core DbContext. 5 | Linq to DB (linq2db) extensions for Entity Framework Core 6 | $(Title) 7 | 8 | LinqToDB.EntityFrameworkCore 9 | bin\$(Configuration)\$(TargetFramework)\linq2db.EntityFrameworkCore.xml 10 | 11 | 12 | EF1001 13 | 14 | 15 | 16 | portable 17 | true 18 | true 19 | 20 | 21 | 22 | 23 | 24 | 25 | all 26 | runtime; build; native; contentfiles; analyzers 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Tests/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | dotnet_diagnostic.NUnit4001.severity = none 3 | -------------------------------------------------------------------------------- /Tests/Directory.Build.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | net8.0 6 | 7 | $(NoWarn);CS1591 8 | 9 | 10 | 11 | 12 | 13 | all 14 | runtime; build; native; contentfiles; analyzers; buildtransitive 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Interceptors/Extensions/LinqToDBContextOptionsBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using LinqToDB.Interceptors; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Interceptors.Extensions 6 | { 7 | public static class LinqToDBContextOptionsBuilderExtensions 8 | { 9 | public static void UseEfCoreRegisteredInterceptorsIfPossible(this LinqToDBContextOptionsBuilder builder) 10 | { 11 | var coreEfExtension = builder.DbContextOptions.FindExtension(); 12 | if (coreEfExtension?.Interceptors != null) 13 | { 14 | foreach (var comboInterceptor in coreEfExtension.Interceptors.OfType()) 15 | { 16 | builder.AddInterceptor(comboInterceptor); 17 | } 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Interceptors/TestCommandInterceptor.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | using System.Data.Common; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using LinqToDB.Common; 6 | using LinqToDB.Interceptors; 7 | 8 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Interceptors 9 | { 10 | public class TestCommandInterceptor : TestInterceptor, ICommandInterceptor 11 | { 12 | public void AfterExecuteReader(CommandEventData eventData, DbCommand command, CommandBehavior commandBehavior, DbDataReader dataReader) 13 | { 14 | HasInterceptorBeenInvoked = true; 15 | } 16 | 17 | public void BeforeReaderDispose(CommandEventData eventData, DbCommand? command, DbDataReader dataReader) 18 | { 19 | HasInterceptorBeenInvoked = true; 20 | } 21 | 22 | public Task BeforeReaderDisposeAsync(CommandEventData eventData, DbCommand? command, DbDataReader dataReader) 23 | { 24 | HasInterceptorBeenInvoked = true; 25 | return Task.CompletedTask; 26 | } 27 | 28 | public DbCommand CommandInitialized(CommandEventData eventData, DbCommand command) 29 | { 30 | HasInterceptorBeenInvoked = true; 31 | return command; 32 | } 33 | 34 | public Option ExecuteNonQuery(CommandEventData eventData, DbCommand command, Option result) 35 | { 36 | HasInterceptorBeenInvoked = true; 37 | return result; 38 | } 39 | 40 | public Task> ExecuteNonQueryAsync(CommandEventData eventData, DbCommand command, Option result, CancellationToken cancellationToken) 41 | { 42 | HasInterceptorBeenInvoked = true; 43 | return Task.FromResult(result); 44 | } 45 | 46 | public Option ExecuteReader(CommandEventData eventData, DbCommand command, CommandBehavior commandBehavior, Option result) 47 | { 48 | HasInterceptorBeenInvoked = true; 49 | return result; 50 | } 51 | 52 | public Task> ExecuteReaderAsync(CommandEventData eventData, DbCommand command, CommandBehavior commandBehavior, Option result, CancellationToken cancellationToken) 53 | { 54 | HasInterceptorBeenInvoked = true; 55 | return Task.FromResult(result); 56 | } 57 | 58 | public Option ExecuteScalar(CommandEventData eventData, DbCommand command, Option result) 59 | { 60 | HasInterceptorBeenInvoked = true; 61 | return result; 62 | } 63 | 64 | public Task> ExecuteScalarAsync(CommandEventData eventData, DbCommand command, Option result, CancellationToken cancellationToken) 65 | { 66 | HasInterceptorBeenInvoked = true; 67 | return Task.FromResult(result); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Interceptors/TestConnectionInterceptor.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using LinqToDB.Interceptors; 5 | 6 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Interceptors 7 | { 8 | public class TestConnectionInterceptor : TestInterceptor, IConnectionInterceptor 9 | { 10 | public void ConnectionOpened(ConnectionEventData eventData, DbConnection connection) 11 | { 12 | HasInterceptorBeenInvoked = true; 13 | } 14 | 15 | public Task ConnectionOpenedAsync(ConnectionEventData eventData, DbConnection connection, CancellationToken cancellationToken) 16 | { 17 | HasInterceptorBeenInvoked = true; 18 | return Task.CompletedTask; 19 | } 20 | 21 | public void ConnectionOpening(ConnectionEventData eventData, DbConnection connection) 22 | { 23 | HasInterceptorBeenInvoked = true; 24 | } 25 | 26 | public Task ConnectionOpeningAsync(ConnectionEventData eventData, DbConnection connection, CancellationToken cancellationToken) 27 | { 28 | HasInterceptorBeenInvoked = true; 29 | return Task.CompletedTask; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Interceptors/TestDataContextInterceptor.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using LinqToDB.Interceptors; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Interceptors 5 | { 6 | public class TestDataContextInterceptor : TestInterceptor, IDataContextInterceptor 7 | { 8 | public void OnClosed(DataContextEventData eventData) 9 | { 10 | HasInterceptorBeenInvoked = true; 11 | } 12 | 13 | public Task OnClosedAsync(DataContextEventData eventData) 14 | { 15 | HasInterceptorBeenInvoked = true; 16 | return Task.CompletedTask; 17 | } 18 | 19 | public void OnClosing(DataContextEventData eventData) 20 | { 21 | HasInterceptorBeenInvoked = true; 22 | } 23 | 24 | public Task OnClosingAsync(DataContextEventData eventData) 25 | { 26 | HasInterceptorBeenInvoked = true; 27 | return Task.CompletedTask; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Interceptors/TestEntityServiceInterceptor.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.Interceptors; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Interceptors 4 | { 5 | public class TestEntityServiceInterceptor : TestInterceptor, IEntityServiceInterceptor 6 | { 7 | public object EntityCreated(EntityCreatedEventData eventData, object entity) 8 | { 9 | HasInterceptorBeenInvoked = true; 10 | return entity; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Interceptors/TestInterceptor.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Interceptors 2 | { 3 | public abstract class TestInterceptor 4 | { 5 | public bool HasInterceptorBeenInvoked { get; protected set; } 6 | 7 | public void ResetInvocations() 8 | { 9 | HasInterceptorBeenInvoked = false; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/LinqToDB.EntityFrameworkCore.BaseTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Logging/LogMessageEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging 4 | { 5 | internal readonly record struct LogMessageEntry( 6 | string Message, 7 | string? TimeStamp = null, 8 | string? LevelString = null, 9 | ConsoleColor? LevelBackground = null, 10 | ConsoleColor? LevelForeground = null, 11 | ConsoleColor? MessageColor = null, 12 | bool LogAsError = false); 13 | } 14 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Logging/NullExternalScopeProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Extensions.Logging; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging 5 | { 6 | /// 7 | /// Scope provider that does nothing. 8 | /// 9 | internal sealed class NullExternalScopeProvider : IExternalScopeProvider 10 | { 11 | private NullExternalScopeProvider() 12 | { 13 | } 14 | 15 | /// 16 | /// Returns a cached instance of . 17 | /// 18 | public static IExternalScopeProvider Instance { get; } = new NullExternalScopeProvider(); 19 | 20 | /// 21 | void IExternalScopeProvider.ForEachScope(Action callback, TState state) 22 | { 23 | } 24 | 25 | /// 26 | IDisposable IExternalScopeProvider.Push(object? state) 27 | { 28 | return NullScope.Instance; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Logging/NullScope.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging 4 | { 5 | internal sealed class NullScope : IDisposable 6 | { 7 | public static NullScope Instance { get; } = new NullScope(); 8 | 9 | private NullScope() 10 | { 11 | } 12 | 13 | /// 14 | public void Dispose() 15 | { 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Logging/TestLoggerExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using Microsoft.Extensions.DependencyInjection.Extensions; 4 | using Microsoft.Extensions.Logging; 5 | using Microsoft.Extensions.Logging.Configuration; 6 | using Microsoft.Extensions.Logging.Console; 7 | 8 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging 9 | { 10 | public static class TestLoggerExtensions 11 | { 12 | /// 13 | /// Adds a console logger named 'Console' to the factory. 14 | /// 15 | /// The to use. 16 | public static ILoggingBuilder AddTestLogger(this ILoggingBuilder builder) 17 | { 18 | builder.AddConfiguration(); 19 | 20 | builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); 21 | LoggerProviderOptions.RegisterProviderOptions(builder.Services); 22 | return builder; 23 | } 24 | 25 | /// 26 | /// Adds a console logger named 'Console' to the factory. 27 | /// 28 | /// The to use. 29 | /// A delegate to configure the . 30 | public static ILoggingBuilder AddTestLogger(this ILoggingBuilder builder, Action configure) 31 | { 32 | ArgumentNullException.ThrowIfNull(configure); 33 | 34 | builder.AddTestLogger(); 35 | builder.Services.Configure(configure); 36 | 37 | return builder; 38 | } 39 | }} 40 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Logging/TestLoggerProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using Microsoft.Extensions.Logging; 4 | using Microsoft.Extensions.Logging.Console; 5 | using Microsoft.Extensions.Options; 6 | 7 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging 8 | { 9 | /// 10 | /// A provider of instances. 11 | /// 12 | [ProviderAlias("Console")] 13 | public sealed class TestLoggerProvider : ILoggerProvider, ISupportExternalScope 14 | { 15 | private readonly IOptionsMonitor _options; 16 | private readonly ConcurrentDictionary _loggers; 17 | 18 | private readonly IDisposable? _optionsReloadToken; 19 | private IExternalScopeProvider _scopeProvider = NullExternalScopeProvider.Instance; 20 | 21 | /// 22 | /// Creates an instance of . 23 | /// 24 | /// The options to create instances with. 25 | public TestLoggerProvider(IOptionsMonitor options) 26 | { 27 | _options = options; 28 | _loggers = new ConcurrentDictionary(); 29 | 30 | ReloadLoggerOptions(options.CurrentValue); 31 | _optionsReloadToken = _options.OnChange(ReloadLoggerOptions); 32 | } 33 | 34 | private void ReloadLoggerOptions(ConsoleLoggerOptions options) 35 | { 36 | foreach (var logger in _loggers) 37 | { 38 | logger.Value.Options = options; 39 | } 40 | } 41 | 42 | /// 43 | public ILogger CreateLogger(string categoryName) 44 | { 45 | return _loggers.GetOrAdd(categoryName, loggerName => new TestLogger(loggerName) 46 | { 47 | Options = _options.CurrentValue, 48 | ScopeProvider = _scopeProvider 49 | }); 50 | } 51 | 52 | /// 53 | public void Dispose() 54 | { 55 | _optionsReloadToken?.Dispose(); 56 | } 57 | 58 | /// 59 | public void SetScopeProvider(IExternalScopeProvider scopeProvider) 60 | { 61 | _scopeProvider = scopeProvider; 62 | 63 | foreach (var logger in _loggers) 64 | { 65 | logger.Value.ScopeProvider = _scopeProvider; 66 | } 67 | 68 | } 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/ForMapping/ForMappingContextBase.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.ForMapping 4 | { 5 | public abstract class ForMappingContextBase : DbContext 6 | { 7 | protected ForMappingContextBase(DbContextOptions options) : base(options) 8 | { 9 | } 10 | 11 | public DbSet WithIdentity { get; set; } = null!; 12 | public DbSet NoIdentity { get; set; } = null!; 13 | public DbSet UIntTable { get; set; } = null!; 14 | public DbSet StringTypes { get; set; } = null!; 15 | public DbSet Types { get; set; } = null!; 16 | 17 | public DbSet WithDuplicateProperties { get; set; } = null!; 18 | 19 | public DbSet WithInheritance { get; set; } = null!; 20 | public DbSet WithInheritanceA { get; set; } = null!; 21 | public DbSet WithInheritanceA1 { get; set; } = null!; 22 | public DbSet WithInheritanceA2 { get; set; } = null!; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/ForMapping/NoIdentity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.ForMapping 4 | { 5 | public class NoIdentity 6 | { 7 | public Guid Id { get; set; } 8 | public string Name { get; set; } = null!; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/ForMapping/StringTypes.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.ForMapping 4 | { 5 | public class StringTypes 6 | { 7 | [Key] 8 | public int Id { get; set; } 9 | 10 | public string? AsciiString { get; set; } 11 | 12 | public string? UnicodeString { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/ForMapping/TypesTable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.ForMapping 5 | { 6 | public class TypesTable 7 | { 8 | [Key] 9 | public int Id { get; set; } 10 | 11 | public DateTime? DateTime { get; set; } 12 | public string? String { get; set; } 13 | 14 | // add more if needed for tests 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/ForMapping/UIntTable.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.ForMapping 4 | { 5 | public class UIntTable 6 | { 7 | [Key] 8 | public int ID { get; set; } 9 | 10 | public ushort Field16 { get; set; } 11 | public uint Field32 { get; set; } 12 | public ulong Field64 { get; set; } 13 | public ushort? Field16N { get; set; } 14 | public uint? Field32N { get; set; } 15 | public ulong? Field64N { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/ForMapping/WithDuplicateProperties.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.ForMapping 4 | { 5 | 6 | public class WithDuplicatePropertiesBase 7 | { 8 | [Key] 9 | public int Id { get; set; } 10 | 11 | public virtual string? Value { get; set; } 12 | } 13 | 14 | public class WithDuplicateProperties : WithDuplicatePropertiesBase 15 | { 16 | public new int? Value { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/ForMapping/WithIdentity.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.ForMapping 2 | { 3 | public class WithIdentity 4 | { 5 | public int Id { get; set; } 6 | public string Name { get; set; } = null!; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/ForMapping/WithInheritance.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.ForMapping 2 | { 3 | public class WithInheritance 4 | { 5 | public int Id { get; set; } 6 | public string Discriminator { get; set; } = null!; 7 | } 8 | 9 | public class WithInheritanceA : WithInheritance 10 | { 11 | 12 | } 13 | 14 | public class WithInheritanceA1 : WithInheritanceA 15 | { 16 | 17 | } 18 | 19 | public class WithInheritanceA2 : WithInheritanceA 20 | { 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/BaseEntity.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 2 | { 3 | public class BaseEntity : ISoftDelete 4 | { 5 | public bool IsDeleted { get; set; } 6 | } 7 | 8 | public interface ISoftDelete 9 | { 10 | public bool IsDeleted { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/Category.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 4 | { 5 | public class Category : BaseEntity 6 | { 7 | public Category() 8 | { 9 | Products = new HashSet(); 10 | } 11 | 12 | public int CategoryId { get; set; } 13 | public string CategoryName { get; set; } = null!; 14 | public string? Description { get; set; } 15 | public byte[]? Picture { get; set; } 16 | 17 | public ICollection Products { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/Customer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 4 | { 5 | public class Customer : BaseEntity 6 | { 7 | public Customer() 8 | { 9 | CustomerCustomerDemo = new HashSet(); 10 | Orders = new HashSet(); 11 | } 12 | 13 | public string CustomerId { get; set; } = null!; 14 | public string CompanyName { get; set; } = null!; 15 | public string? ContactName { get; set; } 16 | public string? ContactTitle { get; set; } 17 | public string? Address { get; set; } 18 | public string? City { get; set; } 19 | public string? Region { get; set; } 20 | public string? PostalCode { get; set; } 21 | public string? Country { get; set; } 22 | public string? Phone { get; set; } 23 | public string? Fax { get; set; } 24 | 25 | public ICollection CustomerCustomerDemo { get; set; } 26 | public ICollection Orders { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/CustomerCustomerDemo.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 2 | { 3 | public class CustomerCustomerDemo : BaseEntity 4 | { 5 | public string CustomerId { get; set; } = null!; 6 | public string CustomerTypeId { get; set; } = null!; 7 | 8 | public Customer Customer { get; set; } = null!; 9 | public CustomerDemographics CustomerType { get; set; } = null!; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/CustomerDemographics.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 4 | { 5 | public class CustomerDemographics : BaseEntity 6 | { 7 | public CustomerDemographics() 8 | { 9 | CustomerCustomerDemo = new HashSet(); 10 | } 11 | 12 | public string CustomerTypeId { get; set; } = null!; 13 | public string? CustomerDesc { get; set; } 14 | 15 | public ICollection CustomerCustomerDemo { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/CustomerOrderHistory.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 3 | { 4 | public class CustomerOrderHistory : BaseEntity 5 | { 6 | public string ProductName { get; set; } = null!; 7 | 8 | public int Total { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/CustomerQuery.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 5 | { 6 | public class CustomerQuery : BaseEntity 7 | { 8 | public string CompanyName { get; set; } = null!; 9 | public int OrderCount { get; set; } 10 | public string SearchTerm { get; set; } = null!; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/CustomerView.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | 6 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 7 | { 8 | public class CustomerView : BaseEntity 9 | { 10 | public string? CompanyName { get; set; } 11 | public string? ContactName { get; set; } 12 | public string? ContactTitle { get; set; } 13 | public string? Address { get; set; } 14 | public string? City { get; set; } 15 | 16 | [NotMapped] 17 | public bool IsLondon => City == "London"; 18 | 19 | protected bool Equals(CustomerView other) 20 | => string.Equals(CompanyName, other.CompanyName); 21 | 22 | public override bool Equals(object? obj) 23 | { 24 | if (obj is null) 25 | { 26 | return false; 27 | } 28 | 29 | return ReferenceEquals(this, obj) 30 | ? true 31 | : obj.GetType() == GetType() 32 | && Equals((CustomerView)obj); 33 | } 34 | 35 | public static bool operator ==(CustomerView left, CustomerView right) 36 | => Equals(left, right); 37 | 38 | public static bool operator !=(CustomerView left, CustomerView right) 39 | => !Equals(left, right); 40 | 41 | public override int GetHashCode() 42 | // ReSharper disable once NonReadonlyMemberInGetHashCode 43 | => CompanyName?.GetHashCode() ?? 0; 44 | 45 | public override string ToString() 46 | => "CustomerView " + CompanyName; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/Employee.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 5 | { 6 | public class Employee : BaseEntity 7 | { 8 | public Employee() 9 | { 10 | EmployeeTerritories = new HashSet(); 11 | InverseReportsToNavigation = new HashSet(); 12 | Orders = new HashSet(); 13 | } 14 | 15 | public int EmployeeId { get; set; } 16 | public string LastName { get; set; } = null!; 17 | public string FirstName { get; set; } = null!; 18 | public string? Title { get; set; } 19 | public string? TitleOfCourtesy { get; set; } 20 | public DateTime? BirthDate { get; set; } 21 | public DateTime? HireDate { get; set; } 22 | public string? Address { get; set; } 23 | public string? City { get; set; } 24 | public string? Region { get; set; } 25 | public string? PostalCode { get; set; } 26 | public string? Country { get; set; } 27 | public string? HomePhone { get; set; } 28 | public string? Extension { get; set; } 29 | public byte[]? Photo { get; set; } 30 | public string? Notes { get; set; } 31 | public int? ReportsTo { get; set; } 32 | public string? PhotoPath { get; set; } 33 | 34 | public Employee? ReportsToNavigation { get; set; } 35 | public ICollection EmployeeTerritories { get; set; } 36 | public ICollection InverseReportsToNavigation { get; set; } 37 | public ICollection Orders { get; set; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/EmployeeTerritory.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 2 | { 3 | public class EmployeeTerritory : BaseEntity 4 | { 5 | public int EmployeeId { get; set; } 6 | public string TerritoryId { get; set; } = null!; 7 | 8 | public Employee Employee { get; set; } = null!; 9 | public Territory Territory { get; set; } = null!; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/Order.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 5 | { 6 | public class Order : BaseEntity 7 | { 8 | public Order() 9 | { 10 | OrderDetails = new HashSet(); 11 | } 12 | 13 | public int OrderId { get; set; } 14 | public string? CustomerId { get; set; } 15 | public int? EmployeeId { get; set; } 16 | public DateTime? OrderDate { get; set; } 17 | public DateTime? RequiredDate { get; set; } 18 | public DateTime? ShippedDate { get; set; } 19 | public int? ShipVia { get; set; } 20 | public decimal? Freight { get; set; } 21 | public string? ShipName { get; set; } 22 | public string? ShipAddress { get; set; } 23 | public string? ShipCity { get; set; } 24 | public string? ShipRegion { get; set; } 25 | public string? ShipPostalCode { get; set; } 26 | public string? ShipCountry { get; set; } 27 | 28 | public Customer? Customer { get; set; } 29 | public Employee? Employee { get; set; } 30 | public Shipper? ShipViaNavigation { get; set; } 31 | public ICollection OrderDetails { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/OrderDetail.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 2 | { 3 | public class OrderDetail : BaseEntity 4 | { 5 | public int OrderId { get; set; } 6 | public int ProductId { get; set; } 7 | public decimal UnitPrice { get; set; } 8 | public short Quantity { get; set; } 9 | public float Discount { get; set; } 10 | 11 | public Order Order { get; set; } = null!; 12 | public Product Product { get; set; } = null!; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/Product.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 4 | { 5 | public class Product : BaseEntity 6 | { 7 | public Product() 8 | { 9 | OrderDetails = new HashSet(); 10 | } 11 | 12 | public int ProductId { get; set; } 13 | public string ProductName { get; set; } = null!; 14 | public int? SupplierId { get; set; } 15 | public int? CategoryId { get; set; } 16 | public string? QuantityPerUnit { get; set; } 17 | public decimal? UnitPrice { get; set; } 18 | public short? UnitsInStock { get; set; } 19 | public short? UnitsOnOrder { get; set; } 20 | public short? ReorderLevel { get; set; } 21 | public bool Discontinued { get; set; } 22 | 23 | public Category? Category { get; set; } 24 | public Supplier? Supplier { get; set; } 25 | public ICollection OrderDetails { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/Region.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 4 | { 5 | public partial class Region : BaseEntity 6 | { 7 | public Region() 8 | { 9 | Territories = new HashSet(); 10 | } 11 | 12 | public int RegionId { get; set; } 13 | public string RegionDescription { get; set; } = null!; 14 | 15 | public ICollection Territories { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/Shipper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 4 | { 5 | public class Shipper : BaseEntity 6 | { 7 | public Shipper() 8 | { 9 | Orders = new HashSet(); 10 | } 11 | 12 | public int ShipperId { get; set; } 13 | public string CompanyName { get; set; } = null!; 14 | public string? Phone { get; set; } 15 | 16 | public ICollection Orders { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/Supplier.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 4 | { 5 | public class Supplier : BaseEntity 6 | { 7 | public Supplier() 8 | { 9 | Products = new HashSet(); 10 | } 11 | 12 | public int SupplierId { get; set; } 13 | public string CompanyName { get; set; } = null!; 14 | public string? ContactName { get; set; } 15 | public string? ContactTitle { get; set; } 16 | public string? Address { get; set; } 17 | public string? City { get; set; } 18 | public string? Region { get; set; } 19 | public string? PostalCode { get; set; } 20 | public string? Country { get; set; } 21 | public string? Phone { get; set; } 22 | public string? Fax { get; set; } 23 | public string? HomePage { get; set; } 24 | 25 | public ICollection Products { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/Territory.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind 4 | { 5 | public class Territory : BaseEntity 6 | { 7 | public Territory() 8 | { 9 | EmployeeTerritories = new HashSet(); 10 | } 11 | 12 | public string TerritoryId { get; set; } = null!; 13 | public string TerritoryDescription { get; set; } = null!; 14 | public int RegionId { get; set; } 15 | 16 | public Region Region { get; set; } = null!; 17 | public ICollection EmployeeTerritories { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.BaseTests/TestUtils.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Logging; 2 | using Microsoft.Extensions.Logging; 3 | using Microsoft.Extensions.Logging.Console; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.BaseTests 6 | { 7 | public static class TestUtils 8 | { 9 | public static readonly ILoggerFactory LoggerFactory = 10 | Microsoft.Extensions.Logging.LoggerFactory.Create(builder => 11 | { 12 | builder.AddFilter("Microsoft", LogLevel.Information) 13 | .AddFilter("System", LogLevel.Warning) 14 | .AddFilter("LinqToDB.EntityFrameworkCore.Test", LogLevel.Information) 15 | 16 | .AddTestLogger(o => 17 | { 18 | o.FormatterName = ConsoleFormatterNames.Simple; 19 | }); 20 | }); 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.FSharpTests/LinqToDB.EntityFrameworkCore.FSharpTests.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 5 | true 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.FSharpTests/Tests.fs: -------------------------------------------------------------------------------- 1 | module LinqToDB.EntityFrameworkCore.FSharpTests 2 | 3 | open System.Linq 4 | open LinqToDB 5 | open System.ComponentModel.DataAnnotations 6 | open System.ComponentModel.DataAnnotations.Schema 7 | open Microsoft.EntityFrameworkCore 8 | open EntityFrameworkCore.FSharp.Extensions 9 | open NUnit.Framework 10 | 11 | [] 12 | type WithIdentity = { 13 | [] 14 | [] 15 | Id : int 16 | Name : string 17 | } 18 | 19 | type AppDbContext(options: DbContextOptions) = 20 | inherit DbContext(options) 21 | 22 | [] val mutable WithIdentity : DbSet 23 | member this.CompaniesInformation 24 | with get() = this.WithIdentity 25 | and set v = this.WithIdentity <- v 26 | 27 | type TestDbContextFactory() = 28 | member this.CreateDbContext() = 29 | let options = new DbContextOptionsBuilder() 30 | options.UseSqlite("DataSource=:memory:").UseFSharpTypes() |> ignore 31 | new AppDbContext(options.Options) 32 | 33 | [] 34 | type Tests() = 35 | 36 | [] 37 | member this.TestLeftJoin() = 38 | let context = TestDbContextFactory().CreateDbContext() 39 | let q = 40 | context 41 | .WithIdentity 42 | .Join( 43 | context.WithIdentity, 44 | (fun p -> p.Id), 45 | (fun c -> c.Id), 46 | (fun p c -> 47 | {| 48 | Person = p 49 | Company = c 50 | |}) ) 51 | .LeftJoin( 52 | context.WithIdentity, 53 | (fun partialPerson cInfo -> partialPerson.Company.Id = cInfo.Id), 54 | (fun partialPerson cInfo -> 55 | {| 56 | Company = partialPerson.Company 57 | CompanyInformation = cInfo 58 | Person = partialPerson.Person 59 | |}) ) 60 | //q.ToArray() |> ignore 61 | q.ToLinqToDB().ToString() |> ignore 62 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/ForMappingTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using LinqToDB.EntityFrameworkCore.BaseTests; 3 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.ForMapping; 4 | using LinqToDB.EntityFrameworkCore.PomeloMySql.Tests.Models.ForMapping; 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace LinqToDB.EntityFrameworkCore.PomeloMySql.Tests 8 | { 9 | public class ForMappingTests : ForMappingTestsBase 10 | { 11 | private bool _isDbCreated; 12 | 13 | protected override ForMappingContextBase CreateContext(Func? optionsSetter = null) 14 | { 15 | var optionsBuilder = new DbContextOptionsBuilder(); 16 | //var connectionString = "Server=DBHost;Port=3306;Database=TestData;Uid=TestUser;Pwd=TestPassword;charset=utf8;"; 17 | var connectionString = "Server=localhost;Port=3316;Database=TestData;Uid=root;Pwd=root;charset=utf8;"; 18 | optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)); 19 | optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory); 20 | 21 | if (optionsSetter! != null) 22 | optionsBuilder.UseLinqToDB(builder => builder.AddCustomOptions(optionsSetter)); 23 | 24 | var options = optionsBuilder.Options; 25 | var ctx = new ForMappingContext(options); 26 | 27 | if (!_isDbCreated) 28 | { 29 | ctx.Database.EnsureDeleted(); 30 | ctx.Database.EnsureCreated(); 31 | 32 | _isDbCreated = true; 33 | } 34 | 35 | return ctx; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/Models/ForMapping/ForMappingContext.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.ForMapping; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.PomeloMySql.Tests.Models.ForMapping 5 | { 6 | public class ForMappingContext : ForMappingContextBase 7 | { 8 | 9 | public ForMappingContext(DbContextOptions options) : base(options) 10 | { 11 | 12 | } 13 | 14 | protected override void OnModelCreating(ModelBuilder modelBuilder) 15 | { 16 | modelBuilder.Entity(b => 17 | { 18 | b.HasKey(e => e.Id); 19 | 20 | b.Property(e => e.Id) 21 | .UseMySqlIdentityColumn(); 22 | }); 23 | 24 | modelBuilder.Entity(b => 25 | { 26 | b.HasKey(e => e.Id); 27 | }); 28 | 29 | modelBuilder.Entity(b => 30 | { 31 | b.HasDiscriminator(x => x.Discriminator); 32 | }); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/Models/Northwind.Mapping/CategoriesMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class CategoriesMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | 12 | builder.HasKey(e => e.CategoryId); 13 | 14 | builder.HasIndex(e => e.CategoryName) 15 | .HasDatabaseName("CategoryName"); 16 | 17 | builder.Property(e => e.CategoryId).HasColumnName("CategoryID") 18 | .ValueGeneratedNever(); 19 | 20 | builder.Property(e => e.CategoryName) 21 | .IsRequired() 22 | .HasMaxLength(15); 23 | 24 | builder.Property(e => e.Description).HasColumnType("text"); 25 | 26 | builder.Property(e => e.Picture).HasColumnType("blob"); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/Models/Northwind.Mapping/CustomerCustomerDemoMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class CustomerCustomerDemoMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | 12 | builder.HasKey(e => new { e.CustomerId, e.CustomerTypeId }); 13 | 14 | builder.Property(e => e.CustomerId) 15 | .HasColumnName("CustomerID") 16 | .HasMaxLength(5); 17 | 18 | builder.Property(e => e.CustomerTypeId) 19 | .HasColumnName("CustomerTypeID") 20 | .HasMaxLength(10); 21 | 22 | builder.HasOne(d => d.Customer) 23 | .WithMany(p => p.CustomerCustomerDemo) 24 | .HasForeignKey(d => d.CustomerId) 25 | .OnDelete(DeleteBehavior.ClientSetNull) 26 | .HasConstraintName("FK_CustomerCustomerDemo_Customers"); 27 | 28 | builder.HasOne(d => d.CustomerType) 29 | .WithMany(p => p.CustomerCustomerDemo) 30 | .HasForeignKey(d => d.CustomerTypeId) 31 | .OnDelete(DeleteBehavior.ClientSetNull) 32 | .HasConstraintName("FK_CustomerCustomerDemo"); 33 | 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/Models/Northwind.Mapping/CustomerDemographicsMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class CustomerDemographicsMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => e.CustomerTypeId); 12 | 13 | builder.Property(e => e.CustomerTypeId) 14 | .HasColumnName("CustomerTypeID") 15 | .HasMaxLength(10) 16 | .ValueGeneratedNever(); 17 | 18 | builder.Property(e => e.CustomerDesc).HasColumnType("text"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/Models/Northwind.Mapping/CustomersMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class CustomersMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | 12 | builder.HasKey(e => e.CustomerId); 13 | 14 | builder.HasIndex(e => e.City) 15 | .HasDatabaseName("City"); 16 | 17 | builder.HasIndex(e => e.CompanyName) 18 | .HasDatabaseName("CompanyName"); 19 | 20 | builder.HasIndex(e => e.PostalCode) 21 | .HasDatabaseName("PostalCode"); 22 | 23 | builder.HasIndex(e => e.Region) 24 | .HasDatabaseName("Region"); 25 | 26 | builder.Property(e => e.CustomerId) 27 | .HasColumnName("CustomerID") 28 | .HasMaxLength(5) 29 | .ValueGeneratedNever(); 30 | 31 | builder.Property(e => e.Address).HasMaxLength(60); 32 | builder.Property(e => e.City).HasMaxLength(15); 33 | builder.Property(e => e.CompanyName) 34 | .IsRequired() 35 | .HasMaxLength(40); 36 | 37 | builder.Property(e => e.ContactName).HasMaxLength(30); 38 | builder.Property(e => e.ContactTitle).HasMaxLength(30); 39 | builder.Property(e => e.Country).HasMaxLength(15); 40 | builder.Property(e => e.Fax).HasMaxLength(24); 41 | builder.Property(e => e.Phone).HasMaxLength(24); 42 | builder.Property(e => e.PostalCode).HasMaxLength(10); 43 | builder.Property(e => e.Region).HasMaxLength(15); 44 | 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/Models/Northwind.Mapping/EmployeeTerritoriesMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class EmployeeTerritoriesMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => new { e.EmployeeId, e.TerritoryId }); 12 | 13 | builder.Property(e => e.EmployeeId).HasColumnName("EmployeeID"); 14 | 15 | builder.Property(e => e.TerritoryId) 16 | .HasColumnName("TerritoryID") 17 | .HasMaxLength(20); 18 | 19 | builder.HasOne(d => d.Employee) 20 | .WithMany(p => p.EmployeeTerritories) 21 | .HasForeignKey(d => d.EmployeeId) 22 | .OnDelete(DeleteBehavior.ClientSetNull) 23 | .HasConstraintName("FK_EmployeeTerritories_Employees"); 24 | 25 | builder.HasOne(d => d.Territory) 26 | .WithMany(p => p.EmployeeTerritories) 27 | .HasForeignKey(d => d.TerritoryId) 28 | .OnDelete(DeleteBehavior.ClientSetNull) 29 | .HasConstraintName("FK_EmployeeTerritories_Territories"); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/Models/Northwind.Mapping/EmployeesMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class EmployeesMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => e.EmployeeId); 12 | 13 | builder.HasIndex(e => e.LastName) 14 | .HasDatabaseName("LastName"); 15 | 16 | builder.HasIndex(e => e.PostalCode) 17 | .HasDatabaseName("PostalCode"); 18 | 19 | builder.Property(e => e.EmployeeId).HasColumnName("EmployeeID") 20 | .ValueGeneratedNever(); 21 | 22 | builder.Property(e => e.Address).HasMaxLength(60); 23 | 24 | builder.Property(e => e.BirthDate).HasColumnType("datetime"); 25 | 26 | builder.Property(e => e.City).HasMaxLength(15); 27 | 28 | builder.Property(e => e.Country).HasMaxLength(15); 29 | 30 | builder.Property(e => e.Extension).HasMaxLength(4); 31 | 32 | builder.Property(e => e.FirstName) 33 | .IsRequired() 34 | .HasMaxLength(10); 35 | 36 | builder.Property(e => e.HireDate).HasColumnType("datetime"); 37 | 38 | builder.Property(e => e.HomePhone).HasMaxLength(24); 39 | 40 | builder.Property(e => e.LastName) 41 | .IsRequired() 42 | .HasMaxLength(20); 43 | 44 | builder.Property(e => e.Notes).HasColumnType("text"); 45 | 46 | builder.Property(e => e.Photo).HasColumnType("blob"); 47 | 48 | builder.Property(e => e.PhotoPath).HasMaxLength(255); 49 | 50 | builder.Property(e => e.PostalCode).HasMaxLength(10); 51 | 52 | builder.Property(e => e.Region).HasMaxLength(15); 53 | 54 | builder.Property(e => e.Title).HasMaxLength(30); 55 | 56 | builder.Property(e => e.TitleOfCourtesy).HasMaxLength(25); 57 | 58 | builder.HasOne(d => d.ReportsToNavigation) 59 | .WithMany(p => p.InverseReportsToNavigation) 60 | .HasForeignKey(d => d.ReportsTo) 61 | .HasConstraintName("FK_Employees_Employees"); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/Models/Northwind.Mapping/OrderDetailsMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class OrderDetailsMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => new { e.OrderId, e.ProductId }); 12 | 13 | builder.ToTable("Order Details"); 14 | 15 | builder.HasIndex(e => e.OrderId) 16 | .HasDatabaseName("OrdersOrder_Details"); 17 | 18 | builder.HasIndex(e => e.ProductId) 19 | .HasDatabaseName("ProductsOrder_Details"); 20 | 21 | builder.Property(e => e.OrderId).HasColumnName("OrderID"); 22 | 23 | builder.Property(e => e.ProductId).HasColumnName("ProductID"); 24 | 25 | builder.Property(e => e.Quantity).HasDefaultValue(1); 26 | 27 | builder.Property(e => e.UnitPrice).HasColumnType("decimal(13, 4)"); 28 | 29 | builder.HasOne(d => d.Order) 30 | .WithMany(p => p.OrderDetails) 31 | .HasForeignKey(d => d.OrderId) 32 | .OnDelete(DeleteBehavior.ClientSetNull) 33 | .HasConstraintName("FK_Order_Details_Orders"); 34 | 35 | builder.HasOne(d => d.Product) 36 | .WithMany(p => p.OrderDetails) 37 | .HasForeignKey(d => d.ProductId) 38 | .OnDelete(DeleteBehavior.ClientSetNull) 39 | .HasConstraintName("FK_Order_Details_Products"); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/Models/Northwind.Mapping/OrderMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class OrderMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | 12 | builder.HasKey(e => e.OrderId); 13 | 14 | builder.HasIndex(e => e.CustomerId) 15 | .HasDatabaseName("CustomersOrders"); 16 | 17 | builder.HasIndex(e => e.EmployeeId) 18 | .HasDatabaseName("EmployeesOrders"); 19 | 20 | builder.HasIndex(e => e.OrderDate) 21 | .HasDatabaseName("OrderDate"); 22 | 23 | builder.HasIndex(e => e.ShipPostalCode) 24 | .HasDatabaseName("ShipPostalCode"); 25 | 26 | builder.HasIndex(e => e.ShipVia) 27 | .HasDatabaseName("ShippersOrders"); 28 | 29 | builder.HasIndex(e => e.ShippedDate) 30 | .HasDatabaseName("ShippedDate"); 31 | 32 | builder.Property(e => e.OrderId).HasColumnName("OrderID") 33 | .ValueGeneratedNever(); 34 | 35 | builder.Property(e => e.CustomerId) 36 | .HasColumnName("CustomerID") 37 | .HasMaxLength(5); 38 | 39 | builder.Property(e => e.EmployeeId).HasColumnName("EmployeeID"); 40 | 41 | builder.Property(e => e.Freight) 42 | .HasColumnType("decimal(13, 4)") 43 | .HasDefaultValue(0m); 44 | 45 | builder.Property(e => e.OrderDate).HasColumnType("datetime"); 46 | 47 | builder.Property(e => e.RequiredDate).HasColumnType("datetime"); 48 | 49 | builder.Property(e => e.ShipAddress).HasMaxLength(60); 50 | 51 | builder.Property(e => e.ShipCity).HasMaxLength(15); 52 | 53 | builder.Property(e => e.ShipCountry).HasMaxLength(15); 54 | 55 | builder.Property(e => e.ShipName).HasMaxLength(40); 56 | 57 | builder.Property(e => e.ShipPostalCode).HasMaxLength(10); 58 | 59 | builder.Property(e => e.ShipRegion).HasMaxLength(15); 60 | 61 | builder.Property(e => e.ShippedDate).HasColumnType("datetime"); 62 | 63 | builder.HasOne(d => d.Customer) 64 | .WithMany(p => p.Orders) 65 | .HasForeignKey(d => d.CustomerId) 66 | .HasConstraintName("FK_Orders_Customers"); 67 | 68 | builder.HasOne(d => d.Employee) 69 | .WithMany(p => p.Orders) 70 | .HasForeignKey(d => d.EmployeeId) 71 | .HasConstraintName("FK_Orders_Employees"); 72 | 73 | builder.HasOne(d => d.ShipViaNavigation) 74 | .WithMany(p => p.Orders) 75 | .HasForeignKey(d => d.ShipVia) 76 | .HasConstraintName("FK_Orders_Shippers"); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/Models/Northwind.Mapping/ProductsMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class ProductsMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => e.ProductId); 12 | 13 | builder.HasIndex(e => e.CategoryId) 14 | .HasDatabaseName("CategoryID"); 15 | 16 | builder.HasIndex(e => e.ProductName) 17 | .HasDatabaseName("ProductName"); 18 | 19 | builder.HasIndex(e => e.SupplierId) 20 | .HasDatabaseName("SuppliersProducts"); 21 | 22 | builder.Property(e => e.ProductId).HasColumnName("ProductID") 23 | .ValueGeneratedNever(); 24 | 25 | builder.Property(e => e.CategoryId).HasColumnName("CategoryID"); 26 | 27 | builder.Property(e => e.ProductName) 28 | .IsRequired() 29 | .HasMaxLength(40); 30 | 31 | builder.Property(e => e.QuantityPerUnit).HasMaxLength(20); 32 | 33 | builder.Property(e => e.ReorderLevel).HasDefaultValue((short)0); 34 | 35 | builder.Property(e => e.SupplierId).HasColumnName("SupplierID"); 36 | 37 | builder.Property(e => e.UnitPrice) 38 | .HasColumnType("decimal(13, 4)") 39 | .HasDefaultValue(0m); 40 | 41 | builder.Property(e => e.UnitsInStock).HasDefaultValue((short)0); 42 | 43 | builder.Property(e => e.UnitsOnOrder).HasDefaultValue((short)0); 44 | 45 | builder.HasOne(d => d.Category) 46 | .WithMany(p => p.Products) 47 | .HasForeignKey(d => d.CategoryId) 48 | .HasConstraintName("FK_Products_Categories"); 49 | 50 | builder.HasOne(d => d.Supplier) 51 | .WithMany(p => p.Products) 52 | .HasForeignKey(d => d.SupplierId) 53 | .HasConstraintName("FK_Products_Suppliers"); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/Models/Northwind.Mapping/RegionMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class RegionMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => e.RegionId); 12 | 13 | builder.Property(e => e.RegionId) 14 | .HasColumnName("RegionID") 15 | .ValueGeneratedNever(); 16 | 17 | builder.Property(e => e.RegionDescription) 18 | .IsRequired() 19 | .HasMaxLength(50); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/Models/Northwind.Mapping/ShippersMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class ShippersMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => e.ShipperId); 12 | 13 | builder.Property(e => e.ShipperId).HasColumnName("ShipperID") 14 | .ValueGeneratedNever(); 15 | 16 | builder.Property(e => e.CompanyName) 17 | .IsRequired() 18 | .HasMaxLength(40); 19 | 20 | builder.Property(e => e.Phone).HasMaxLength(24); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/Models/Northwind.Mapping/SuppliersMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class SuppliersMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | 12 | builder.HasKey(e => e.SupplierId); 13 | 14 | builder.HasIndex(e => e.CompanyName) 15 | .HasDatabaseName("CompanyName"); 16 | 17 | builder.HasIndex(e => e.PostalCode) 18 | .HasDatabaseName("PostalCode"); 19 | 20 | builder.Property(e => e.SupplierId).HasColumnName("SupplierID") 21 | .ValueGeneratedNever(); 22 | 23 | builder.Property(e => e.Address).HasMaxLength(60); 24 | 25 | builder.Property(e => e.City).HasMaxLength(15); 26 | 27 | builder.Property(e => e.CompanyName) 28 | .IsRequired() 29 | .HasMaxLength(40); 30 | 31 | builder.Property(e => e.ContactName).HasMaxLength(30); 32 | 33 | builder.Property(e => e.ContactTitle).HasMaxLength(30); 34 | 35 | builder.Property(e => e.Country).HasMaxLength(15); 36 | 37 | builder.Property(e => e.Fax).HasMaxLength(24); 38 | 39 | builder.Property(e => e.HomePage).HasColumnType("text"); 40 | 41 | builder.Property(e => e.Phone).HasMaxLength(24); 42 | 43 | builder.Property(e => e.PostalCode).HasMaxLength(10); 44 | 45 | builder.Property(e => e.Region).HasMaxLength(15); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/Models/Northwind.Mapping/TerritoriesMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class TerritoriesMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => e.TerritoryId); 12 | 13 | builder.Property(e => e.TerritoryId) 14 | .HasColumnName("TerritoryID") 15 | .HasMaxLength(20) 16 | .ValueGeneratedNever(); 17 | 18 | builder.Property(e => e.RegionId).HasColumnName("RegionID"); 19 | 20 | builder.Property(e => e.TerritoryDescription) 21 | .IsRequired() 22 | .HasMaxLength(50); 23 | 24 | builder.HasOne(d => d.Region) 25 | .WithMany(p => p.Territories) 26 | .HasForeignKey(d => d.RegionId) 27 | .OnDelete(DeleteBehavior.ClientSetNull) 28 | .HasConstraintName("FK_Territories_Region"); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/Models/Northwind/NorthwindContext.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping; 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind 6 | { 7 | public class NorthwindContext : DbContext 8 | { 9 | public DbSet Categories { get; set; } = null!; 10 | public DbSet CustomerCustomerDemo { get; set; } = null!; 11 | public DbSet CustomerDemographics { get; set; } = null!; 12 | public DbSet Customers { get; set; } = null!; 13 | public DbSet Employees { get; set; } = null!; 14 | public DbSet EmployeeTerritories { get; set; } = null!; 15 | public DbSet OrderDetails { get; set; } = null!; 16 | public DbSet Orders { get; set; } = null!; 17 | public DbSet Products { get; set; } = null!; 18 | public DbSet Region { get; set; } = null!; 19 | public DbSet Shippers { get; set; } = null!; 20 | public DbSet Suppliers { get; set; } = null!; 21 | public DbSet Territories { get; set; } = null!; 22 | 23 | public NorthwindContext(DbContextOptions options) : base(options) 24 | { 25 | 26 | } 27 | 28 | protected override void OnModelCreating(ModelBuilder modelBuilder) 29 | { 30 | modelBuilder.ApplyConfiguration(new CategoriesMap()); 31 | modelBuilder.ApplyConfiguration(new CustomerCustomerDemoMap()); 32 | modelBuilder.ApplyConfiguration(new CustomerDemographicsMap()); 33 | modelBuilder.ApplyConfiguration(new CustomersMap()); 34 | modelBuilder.ApplyConfiguration(new EmployeesMap()); 35 | modelBuilder.ApplyConfiguration(new EmployeeTerritoriesMap()); 36 | modelBuilder.ApplyConfiguration(new OrderDetailsMap()); 37 | modelBuilder.ApplyConfiguration(new OrderMap()); 38 | modelBuilder.ApplyConfiguration(new ProductsMap()); 39 | modelBuilder.ApplyConfiguration(new RegionMap()); 40 | modelBuilder.ApplyConfiguration(new ShippersMap()); 41 | modelBuilder.ApplyConfiguration(new SuppliersMap()); 42 | modelBuilder.ApplyConfiguration(new TerritoriesMap()); 43 | 44 | modelBuilder.Entity() 45 | .HasQueryFilter(e => !IsFilterProducts || e.ProductId > 2); 46 | } 47 | 48 | public bool IsFilterProducts { get; set; } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PomeloMySql.Tests/PomeloMySqlTests.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using LinqToDB.Data; 3 | using LinqToDB.EntityFrameworkCore.BaseTests; 4 | using LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind; 5 | using Microsoft.EntityFrameworkCore; 6 | using NUnit.Framework; 7 | 8 | namespace LinqToDB.EntityFrameworkCore.PomeloMySql.Tests 9 | { 10 | public class PomeloMySqlTests : TestsBase 11 | { 12 | private DbContextOptions _options; 13 | 14 | static PomeloMySqlTests() 15 | { 16 | LinqToDBForEFTools.Initialize(); 17 | DataConnection.TurnTraceSwitchOn(); 18 | } 19 | 20 | public PomeloMySqlTests() 21 | { 22 | var optionsBuilder = new DbContextOptionsBuilder(); 23 | //new SqlServerDbContextOptionsBuilder(optionsBuilder); 24 | 25 | //var connectionString = "Server=DBHost;Port=3306;Database=TestData;Uid=TestUser;Pwd=TestPassword;charset=utf8;"; 26 | var connectionString = "Server=localhost;Port=3316;Database=TestData;Uid=root;Pwd=root;charset=utf8;"; 27 | optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)); 28 | 29 | optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory); 30 | 31 | _options = optionsBuilder.Options; 32 | } 33 | 34 | private NorthwindContext CreateMySqlSqlEntitiesContext() 35 | { 36 | var ctx = new NorthwindContext(_options); 37 | ctx.Database.EnsureDeleted(); 38 | ctx.Database.EnsureCreated(); 39 | return ctx; 40 | } 41 | 42 | [Test] 43 | public void SimpleProviderTest() 44 | { 45 | using (var db = CreateMySqlSqlEntitiesContext()) 46 | { 47 | var items = db.Customers.Where(e => e.Address != null).ToLinqToDB().ToArray(); 48 | } 49 | } 50 | 51 | [Test(Description = "https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/issues/1801")] 52 | public void TestFunctionTranslation() 53 | { 54 | using var db = CreateMySqlSqlEntitiesContext(); 55 | var items = db.Customers.Where(e => e.Address!.Contains("anything")).ToLinqToDB().ToArray(); 56 | } 57 | 58 | [Test(Description = "https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/issues/1801")] 59 | public void TestFunctionTranslationParameter() 60 | { 61 | using var db = CreateMySqlSqlEntitiesContext(); 62 | var value = "anything"; 63 | var items = db.Customers.Where(e => e.Address!.Contains(value)).ToLinqToDB().ToArray(); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/ForMappingTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using LinqToDB.EntityFrameworkCore.BaseTests; 3 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.ForMapping; 4 | using LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.Models.ForMapping; 5 | using Microsoft.EntityFrameworkCore; 6 | using NUnit.Framework; 7 | 8 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests 9 | { 10 | [TestFixture] 11 | public class ForMappingTests : ForMappingTestsBase 12 | { 13 | private bool _isDbCreated; 14 | 15 | protected override ForMappingContextBase CreateContext(Func? optionsSetter = null) 16 | { 17 | var optionsBuilder = new DbContextOptionsBuilder(); 18 | //optionsBuilder.UseNpgsql("Server=DBHost;Port=5432;Database=ForMapping;User Id=postgres;Password=TestPassword;Pooling=true;MinPoolSize=10;MaxPoolSize=100;"); 19 | optionsBuilder.UseNpgsql("Server=localhost;Port=5415;Database=ForMapping;User Id=postgres;Password=Password12!;Pooling=true;MinPoolSize=10;MaxPoolSize=100;"); 20 | optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory); 21 | 22 | if (optionsSetter! != null) 23 | optionsBuilder.UseLinqToDB(builder => builder.AddCustomOptions(optionsSetter)); 24 | 25 | var options = optionsBuilder.Options; 26 | var ctx = new ForMappingContext(options); 27 | 28 | if (!_isDbCreated) 29 | { 30 | ctx.Database.EnsureDeleted(); 31 | ctx.Database.EnsureCreated(); 32 | 33 | _isDbCreated = true; 34 | } 35 | 36 | return ctx; 37 | } 38 | 39 | //Disabled, we cannot create such identity table. 40 | public override void TestBulkCopyWithIdentity() 41 | { 42 | } 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/Models/ForMapping/ForMappingContext.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.ForMapping; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.Models.ForMapping 5 | { 6 | public class ForMappingContext : ForMappingContextBase 7 | { 8 | public ForMappingContext(DbContextOptions options) : base(options) 9 | { 10 | } 11 | 12 | protected override void OnModelCreating(ModelBuilder modelBuilder) 13 | { 14 | modelBuilder.Entity(b => 15 | { 16 | b.HasKey(e => e.Id); 17 | 18 | b.Property(e => e.Id) 19 | .UseIdentityAlwaysColumn(); 20 | }); 21 | 22 | modelBuilder.Entity(b => 23 | { 24 | b.HasKey(e => e.Id); 25 | }); 26 | 27 | modelBuilder.Entity(b => 28 | { 29 | b.HasDiscriminator(x => x.Discriminator); 30 | }); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/Models/NpgSqlEntities/EntityWithArrays.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.Models.NpgSqlEntities 5 | { 6 | public class EntityWithArrays 7 | { 8 | [Key] 9 | public int Id { get; set; } 10 | 11 | public Guid[] Guids { get; set; } = null!; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/Models/NpgSqlEntities/EntityWithXmin.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.Models.NpgSqlEntities 4 | { 5 | public class EntityWithXmin 6 | { 7 | [Key] 8 | public int Id { get; set; } 9 | public uint xmin { get; set; } 10 | public string Value { get; set; } = null!; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/Models/NpgSqlEntities/Event.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NpgsqlTypes; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.Models.NpgSqlEntities 5 | { 6 | public class Event 7 | { 8 | public int Id { get; set; } 9 | public string Name { get; set; } = null!; 10 | public NpgsqlRange Duration { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/Models/NpgSqlEntities/EventView.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.Models.NpgSqlEntities 2 | { 3 | public class EventView 4 | { 5 | public string Name { get; set; } = null!; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/Models/NpgSqlEntities/NpgSqlEntitiesContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.Models.NpgSqlEntities 4 | { 5 | public class NpgSqlEntitiesContext : DbContext 6 | { 7 | public NpgSqlEntitiesContext(DbContextOptions options) 8 | : base(options) 9 | { 10 | } 11 | 12 | protected override void OnModelCreating(ModelBuilder modelBuilder) 13 | { 14 | modelBuilder.Entity(entity => 15 | entity.Property(e => e.Duration).HasColumnType("tsrange") 16 | ); 17 | 18 | modelBuilder.Entity(entity => 19 | { 20 | entity.HasNoKey(); 21 | entity.ToView("EventsView", "views"); 22 | }); 23 | 24 | modelBuilder.Entity(entity => 25 | { 26 | }); 27 | 28 | modelBuilder.Entity(entity => 29 | { 30 | entity.Property(nameof(NpgSqlEntities.EntityWithXmin.xmin)).IsRowVersion(); 31 | }); 32 | 33 | modelBuilder.Entity(e => 34 | { 35 | e.Property(e => e.Timestamp1).HasColumnType("timestamp"); 36 | e.Property(e => e.Timestamp2).HasColumnType("timestamp"); 37 | e.Property(e => e.TimestampTZ1).HasColumnType("timestamp with time zone"); 38 | e.Property(e => e.TimestampTZ2).HasColumnType("timestamp with time zone"); 39 | e.Property(e => e.TimestampTZ3).HasColumnType("timestamp with time zone"); 40 | }); 41 | } 42 | 43 | public virtual DbSet Events { get; set; } = null!; 44 | public virtual DbSet EntityWithArrays { get; set; } = null!; 45 | public virtual DbSet EntityWithXmin { get; set; } = null!; 46 | public virtual DbSet TimeStamps { get; set; } = null!; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/Models/NpgSqlEntities/TimeStampEntity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NodaTime; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.Models.NpgSqlEntities 5 | { 6 | public class TimeStampEntity 7 | { 8 | public int Id { get; set; } 9 | public DateTime Timestamp1 { get; set; } 10 | public LocalDateTime Timestamp2 { get; set; } 11 | public DateTime TimestampTZ1 { get; set; } 12 | public DateTimeOffset TimestampTZ2 { get; set; } 13 | public Instant TimestampTZ3 { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/NpgSqlTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using FluentAssertions; 4 | using LinqToDB.Data; 5 | using LinqToDB.DataProvider.PostgreSQL; 6 | using LinqToDB.EntityFrameworkCore.BaseTests; 7 | using LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.Models.NpgSqlEntities; 8 | using Microsoft.EntityFrameworkCore; 9 | using NodaTime; 10 | using NUnit.Framework; 11 | 12 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests 13 | { 14 | public class NpgSqlTests : TestsBase 15 | { 16 | private DbContextOptions _options; 17 | 18 | static NpgSqlTests() 19 | { 20 | LinqToDBForEFTools.Initialize(); 21 | DataConnection.TurnTraceSwitchOn(); 22 | } 23 | 24 | public NpgSqlTests() 25 | { 26 | var optionsBuilder = new DbContextOptionsBuilder(); 27 | 28 | //optionsBuilder.UseNpgsql("Server=DBHost;Port=5432;Database=TestData;User Id=postgres;Password=TestPassword;Pooling=true;MinPoolSize=10;MaxPoolSize=100;", o => o.UseNodaTime()); 29 | optionsBuilder.UseNpgsql("Server=localhost;Port=5415;Database=TestData;User Id=postgres;Password=Password12!;Pooling=true;MinPoolSize=10;MaxPoolSize=100;", o => o.UseNodaTime()); 30 | optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory); 31 | 32 | _options = optionsBuilder.Options; 33 | } 34 | 35 | private NpgSqlEntitiesContext CreateNpgSqlEntitiesContext() 36 | { 37 | var ctx = new NpgSqlEntitiesContext(_options); 38 | ctx.Database.EnsureDeleted(); 39 | ctx.Database.EnsureCreated(); 40 | ctx.Database.ExecuteSqlRaw("create schema \"views\""); 41 | ctx.Database.ExecuteSqlRaw("create view \"views\".\"EventsView\" as select \"Name\" from \"Events\""); 42 | return ctx; 43 | } 44 | 45 | [Test] 46 | public void TestFunctionsMapping() 47 | { 48 | using (var db = CreateNpgSqlEntitiesContext()) 49 | { 50 | var date = DateTime.Now; 51 | 52 | var query = db.Events.Where(e => 53 | e.Duration.Contains(date) || e.Duration.LowerBound == date || e.Duration.UpperBound == date || 54 | e.Duration.IsEmpty || e.Duration.Intersect(e.Duration).IsEmpty); 55 | 56 | var efResult = query.ToArray(); 57 | var l2dbResult = query.ToLinqToDB().ToArray(); 58 | } 59 | } 60 | 61 | [Test] 62 | public void TestViewMapping() 63 | { 64 | using (var db = CreateNpgSqlEntitiesContext()) 65 | { 66 | var query = db.Set().Where(e => 67 | e.Name.StartsWith("any")); 68 | 69 | var efResult = query.ToArray(); 70 | var l2dbResult = query.ToLinqToDB().ToArray(); 71 | } 72 | } 73 | 74 | [Test] 75 | public void TestArray() 76 | { 77 | using (var db = CreateNpgSqlEntitiesContext()) 78 | { 79 | var guids = new Guid[] { Guid.Parse("271425b1-ebe8-400d-b71d-a6e47a460ae3"), 80 | Guid.Parse("b75de94e-6d7b-4c70-bfa1-f8639a6a5b35") }; 81 | 82 | var query = 83 | from m in db.EntityWithArrays.ToLinqToDBTable() 84 | where Sql.Ext.PostgreSQL().Overlaps(m.Guids, guids) 85 | select m; 86 | 87 | query.Invoking(q => q.ToArray()).Should().NotThrow(); 88 | } 89 | } 90 | 91 | [Test] 92 | public void TestConcurrencyToken() 93 | { 94 | using var db = CreateNpgSqlEntitiesContext(); 95 | 96 | var toInsert = Enumerable.Range(1, 10) 97 | .Select(i => new EntityWithXmin { Value = FormattableString.Invariant($"Str{i}") }) 98 | .ToArray(); 99 | 100 | db.BulkCopy(toInsert); 101 | } 102 | 103 | [Test] 104 | public void TestUnnest() 105 | { 106 | using var db = CreateNpgSqlEntitiesContext(); 107 | using var dc = db.CreateLinqToDBConnection(); 108 | 109 | var guids = new Guid[] { Guid.Parse("271425b1-ebe8-400d-b71d-a6e47a460ae3"), 110 | Guid.Parse("b75de94e-6d7b-4c70-bfa1-f8639a6a5b35") }; 111 | 112 | var query = 113 | from m in db.EntityWithArrays.ToLinqToDBTable() 114 | from g in dc.Unnest(m.Guids) 115 | where Sql.Ext.PostgreSQL().Overlaps(m.Guids, guids) 116 | select m; 117 | 118 | query.Invoking(q => q.ToArray()).Should().NotThrow(); 119 | } 120 | 121 | [Test] 122 | public void TestDateTimeKind([Values] DateTimeKind kind) 123 | { 124 | using var db = CreateNpgSqlEntitiesContext(); 125 | using var dc = db.CreateLinqToDBConnection(); 126 | 127 | var dt = new DateTime(DateTime.Now.Ticks, kind); 128 | var dto = DateTimeOffset.Now; 129 | var ins = Instant.FromDateTimeOffset(dto); 130 | var ldt = LocalDateTime.FromDateTime(DateTime.Now); 131 | 132 | db.TimeStamps.Where(e => e.Timestamp1 == dt).ToLinqToDB().ToArray(); 133 | db.TimeStamps.Where(e => e.Timestamp2 == ldt).ToLinqToDB().ToArray(); 134 | db.TimeStamps.Where(e => e.TimestampTZ1 == dt).ToLinqToDB().ToArray(); 135 | db.TimeStamps.Where(e => e.TimestampTZ2 == dto).ToLinqToDB().ToArray(); 136 | db.TimeStamps.Where(e => e.TimestampTZ3 == ins).ToLinqToDB().ToArray(); 137 | } 138 | 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/SampleTests/AAA.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests 5 | { 6 | public class Unit 7 | { 8 | } 9 | 10 | public static class ExceptionExtensions 11 | { 12 | public static Unit Throw(this Exception e) => throw e; 13 | } 14 | 15 | public static class AAA 16 | { 17 | internal static ArrangeResult Arrange(this T @object, Action action) 18 | { 19 | action(@object); 20 | return new ArrangeResult(@object, default); 21 | } 22 | 23 | internal static ArrangeResult Arrange(T @object) 24 | => new(@object, default); 25 | 26 | internal static ArrangeResult Arrange(this TMock mock, Func @object) 27 | where TMock: notnull 28 | => new(@object(mock), mock); 29 | 30 | internal static ActResult Act(this ArrangeResult arrange, Action act) 31 | where T : notnull 32 | where TMock : notnull 33 | { 34 | #pragma warning disable CA1031 // Do not catch general exception types 35 | try 36 | { 37 | act(arrange.Object); 38 | return new ActResult(arrange.Object, arrange.Mock, default); 39 | } 40 | catch (Exception e) 41 | { 42 | return new ActResult(arrange.Object, arrange.Mock, e); 43 | } 44 | #pragma warning restore CA1031 // Do not catch general exception types 45 | } 46 | 47 | internal static ActResult Act(this ArrangeResult arrange, Func act) 48 | where TResult : notnull 49 | where TMock : notnull 50 | { 51 | #pragma warning disable CA1031 // Do not catch general exception types 52 | try 53 | { 54 | return new ActResult(act(arrange.Object), arrange.Mock, default); 55 | } 56 | catch (Exception e) 57 | { 58 | return new ActResult(default, arrange.Mock, e); 59 | } 60 | #pragma warning restore CA1031 // Do not catch general exception types 61 | } 62 | 63 | internal static void Assert(this ActResult act, Action assert) 64 | where T : notnull 65 | where TMock : notnull 66 | { 67 | act.Exception?.Throw(); 68 | assert(act.Object); 69 | } 70 | 71 | internal static void Assert(this ActResult act, Action assert) 72 | where T : notnull 73 | where TMock : notnull 74 | { 75 | act.Exception?.Throw(); 76 | assert(act.Object, act.Mock); 77 | } 78 | 79 | internal static Task> ArrangeAsync(T @object) 80 | => Task.FromResult(new ArrangeResult(@object, default)); 81 | 82 | internal static async Task> Act(this Task> arrange, Func> act) 83 | where TMock : notnull 84 | where TResult : notnull 85 | { 86 | var a = await arrange; 87 | #pragma warning disable CA1031 // Do not catch general exception types 88 | try 89 | { 90 | return new ActResult(await act(a.Object), a.Mock, default); 91 | } 92 | catch (Exception e) 93 | { 94 | return new ActResult(default, a.Mock, e); 95 | } 96 | #pragma warning restore CA1031 // Do not catch general exception types 97 | } 98 | 99 | internal static async Task Assert(this Task> act, Func assert) 100 | where T : notnull 101 | where TMock : notnull 102 | { 103 | var result = await act; 104 | await assert(result.Object); 105 | } 106 | 107 | internal readonly record struct ArrangeResult(T Object, TMock? Mock) 108 | where TMock : notnull; 109 | 110 | internal readonly record struct ActResult(T? Object, TMock? Mock, Exception? Exception) 111 | where T: notnull; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/SampleTests/Child.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests 2 | { 3 | public sealed class Child : IHasWriteableId 4 | { 5 | public Id Id { get; set; } 6 | public Id ParentId { get; set; } 7 | public string Name { get; set; } = null!; 8 | public Entity Parent { get; set; } = null!; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/SampleTests/DataContextExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests 2 | { 3 | public static class DataContextExtensions 4 | { 5 | public static Id Insert(this IDataContext context, T item) 6 | where T : IHasWriteableId 7 | { 8 | item.Id = context.InsertWithInt64Identity(item).AsId(); 9 | return item.Id; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/SampleTests/Detail.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests 4 | { 5 | public sealed class Detail : IHasWriteableId 6 | { 7 | public Id Id { get; set; } 8 | public Id MasterId { get; set; } 9 | public string Name { get; set; } = null!; 10 | public Entity Master { get; set; } = null!; 11 | public IEnumerable Details { get; set; } = null!; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/SampleTests/Entity.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests 4 | { 5 | public sealed class Entity : IHasWriteableId 6 | { 7 | public Id Id { get; set; } 8 | public string Name { get; set; } = null!; 9 | 10 | public IEnumerable Details { get; set; } = null!; 11 | public IEnumerable Children { get; set; } = null!; 12 | public IEnumerable Items { get; set; } = null!; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/SampleTests/Entity2Item.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests 2 | { 3 | public sealed class Entity2Item 4 | { 5 | public Id EntityId { get; set; } 6 | public Entity Entity { get; set; } = null!; 7 | public Id ItemId { get; set; } 8 | 9 | public Entity2Item() 10 | { 11 | } 12 | 13 | public Item Item { get; set; } = null!; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/SampleTests/IHasId.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests 2 | { 3 | public interface IHasId 4 | where T: IHasId 5 | where TId : notnull 6 | { 7 | Id Id { get; } 8 | } 9 | 10 | public interface IHasWriteableId : IHasId 11 | where T: IHasWriteableId 12 | where TId : notnull 13 | { 14 | new Id Id { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/SampleTests/Id.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests 5 | { 6 | public static class Id 7 | { 8 | public static Id AsId(this long id) where T : IHasId => id.AsId(); 9 | 10 | public static Id AsId(this TId id) 11 | where T : IHasId 12 | where TId : notnull 13 | => new(id); 14 | } 15 | 16 | public readonly struct Id : IEquatable> 17 | where T : IHasId 18 | where TId : notnull 19 | { 20 | internal Id(TId value) => Value = value; 21 | TId Value { get; } 22 | 23 | public static implicit operator TId (in Id id) => id.Value; 24 | public static bool operator == (Id left, Id right) 25 | => EqualityComparer.Default.Equals(left.Value, right.Value); 26 | public static bool operator != (Id left, Id right) => !(left == right); 27 | 28 | public override string ToString() => $"{typeof(T).Name}({Value})"; 29 | public bool Equals(Id other) => EqualityComparer.Default.Equals(Value, other.Value); 30 | public override bool Equals(object? obj) => obj is Id other && Equals(other); 31 | public override int GetHashCode() => EqualityComparer.Default.GetHashCode(Value); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/SampleTests/IdValueConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests 6 | { 7 | public sealed class IdValueConverter : ValueConverter, TId> 8 | where T : IHasId 9 | where TId : notnull 10 | { 11 | public IdValueConverter(ConverterMappingHints? mappingHints = null) 12 | : base(id => id, id => id.AsId()) { } 13 | } 14 | 15 | public sealed class IdValueConverterSelector : ValueConverterSelector 16 | { 17 | public IdValueConverterSelector([System.Diagnostics.CodeAnalysis.NotNull] ValueConverterSelectorDependencies dependencies) : base(dependencies) 18 | { 19 | } 20 | 21 | public override IEnumerable Select(Type modelClrType, Type? providerClrType = null) 22 | { 23 | var baseConverters = base.Select(modelClrType, providerClrType); 24 | foreach (var converter in baseConverters) 25 | yield return converter; 26 | 27 | modelClrType = modelClrType.UnwrapNullable(); 28 | providerClrType = providerClrType.UnwrapNullable(); 29 | 30 | if (!modelClrType.IsGenericType) 31 | yield break; 32 | 33 | if (modelClrType.GetGenericTypeDefinition() != typeof(Id<,>)) 34 | yield break; 35 | 36 | var t = modelClrType.GetGenericArguments(); 37 | var key = t[1]; 38 | providerClrType ??= key; 39 | if (key != providerClrType) 40 | yield break; 41 | 42 | var ct = typeof(IdValueConverter<,>).MakeGenericType(key, t[0]); 43 | yield return new ValueConverterInfo 44 | ( 45 | modelClrType, 46 | providerClrType, 47 | i => (ValueConverter)Activator.CreateInstance(ct, i.MappingHints)! 48 | ); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/SampleTests/Item.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests 2 | { 3 | public sealed class Item : IHasWriteableId 4 | { 5 | public Id Id { get; set; } 6 | public string Name { get; set; } = null!; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/SampleTests/QueryableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests 5 | { 6 | public static class QueryableExtensions 7 | { 8 | public static IQueryable AsLinqToDB(this IQueryable queryable, bool l2db) 9 | => l2db ? queryable.ToLinqToDB() : queryable; 10 | 11 | public static IQueryable AsTracking(this IQueryable queryable, bool tracking) 12 | where T : class 13 | => tracking ? queryable.AsTracking() : queryable.AsNoTracking(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/SampleTests/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests 4 | { 5 | public static partial class StringExtensions 6 | { 7 | public static string ToSnakeCase(this string input) 8 | { 9 | if (string.IsNullOrEmpty(input)) 10 | return input; 11 | 12 | var startUnderscores = UnderscoresMatcher().Match(input); 13 | #pragma warning disable CA1308 // Normalize strings to uppercase 14 | return startUnderscores + Replacer().Replace(input, "$1_$2").ToLowerInvariant(); 15 | #pragma warning restore CA1308 // Normalize strings to uppercase 16 | } 17 | 18 | [GeneratedRegex("^_+")] 19 | private static partial Regex UnderscoresMatcher(); 20 | [GeneratedRegex("([a-z0-9])([A-Z])")] 21 | private static partial Regex Replacer(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/SampleTests/SubDetail.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests 2 | { 3 | public sealed class SubDetail : IHasWriteableId 4 | { 5 | public Id Id { get; set; } 6 | public Id MasterId { get; set; } 7 | public string Name { get; set; } = null!; 8 | public Detail Master { get; set; } = null!; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.PostgreSQL.Tests/SampleTests/TypeExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics.CodeAnalysis; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests 5 | { 6 | public static class TypeExtensions 7 | { 8 | [return: NotNullIfNotNull(nameof(type))] 9 | public static Type? UnwrapNullable(this Type? type) 10 | => type == null ? null : Nullable.GetUnderlyingType(type) ?? type; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/ForMappingTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using LinqToDB.EntityFrameworkCore.BaseTests; 3 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.ForMapping; 4 | using LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.ForMapping; 5 | using Microsoft.EntityFrameworkCore; 6 | using NUnit.Framework; 7 | 8 | namespace LinqToDB.EntityFrameworkCore.SQLite.Tests 9 | { 10 | [TestFixture] 11 | public class ForMappingTests : ForMappingTestsBase 12 | { 13 | protected override ForMappingContextBase CreateContext(Func? optionsSetter = null) 14 | { 15 | var optionsBuilder = new DbContextOptionsBuilder(); 16 | optionsBuilder.UseSqlite("DataSource=:memory:"); 17 | optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory); 18 | 19 | if (optionsSetter! != null) 20 | optionsBuilder.UseLinqToDB(builder => builder.AddCustomOptions(optionsSetter)); 21 | 22 | var options = optionsBuilder.Options; 23 | var ctx = new ForMappingContext(options); 24 | 25 | ctx.Database.OpenConnection(); 26 | ctx.Database.EnsureCreated(); 27 | 28 | return ctx; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/Models/ForMapping/ForMappingContext.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.ForMapping; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.ForMapping 5 | { 6 | public class ForMappingContext : ForMappingContextBase 7 | { 8 | public ForMappingContext(DbContextOptions options) : base(options) 9 | { 10 | } 11 | 12 | protected override void OnModelCreating(ModelBuilder modelBuilder) 13 | { 14 | modelBuilder.Entity(b => 15 | { 16 | b.HasKey(e => e.Id); 17 | }); 18 | 19 | modelBuilder.Entity(b => 20 | { 21 | b.HasKey(e => e.Id); 22 | }); 23 | 24 | modelBuilder.Entity(b => 25 | { 26 | b.HasDiscriminator(x => x.Discriminator); 27 | }); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/Models/Northwind.Mapping/CategoriesMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping 6 | { 7 | public class CategoriesMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => e.CategoryId); 12 | 13 | builder.HasIndex(e => e.CategoryName) 14 | .HasDatabaseName("CategoryName"); 15 | 16 | builder.Property(e => e.CategoryId).HasColumnName("CategoryID") 17 | /*.ValueGeneratedNever()*/; 18 | 19 | builder.Property(e => e.CategoryName) 20 | .IsRequired() 21 | .HasMaxLength(15); 22 | 23 | builder.Property(e => e.Description).HasColumnType("text"); 24 | 25 | builder.Property(e => e.Picture).HasColumnType("blob"); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/Models/Northwind.Mapping/CustomerCustomerDemoMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping 6 | { 7 | public class CustomerCustomerDemoMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => new { e.CustomerId, e.CustomerTypeId }); 12 | 13 | builder.Property(e => e.CustomerId) 14 | .HasColumnName("CustomerID") 15 | .HasMaxLength(5); 16 | 17 | builder.Property(e => e.CustomerTypeId) 18 | .HasColumnName("CustomerTypeID") 19 | .HasMaxLength(10); 20 | 21 | builder.HasOne(d => d.Customer) 22 | .WithMany(p => p.CustomerCustomerDemo) 23 | .HasForeignKey(d => d.CustomerId) 24 | .OnDelete(DeleteBehavior.ClientSetNull) 25 | .HasConstraintName("FK_CustomerCustomerDemo_Customers"); 26 | 27 | builder.HasOne(d => d.CustomerType) 28 | .WithMany(p => p.CustomerCustomerDemo) 29 | .HasForeignKey(d => d.CustomerTypeId) 30 | .OnDelete(DeleteBehavior.ClientSetNull) 31 | .HasConstraintName("FK_CustomerCustomerDemo"); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/Models/Northwind.Mapping/CustomerDemographicsMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping 6 | { 7 | public class CustomerDemographicsMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => e.CustomerTypeId); 12 | 13 | builder.Property(e => e.CustomerTypeId) 14 | .HasColumnName("CustomerTypeID") 15 | .HasMaxLength(10) 16 | .ValueGeneratedNever(); 17 | 18 | builder.Property(e => e.CustomerDesc).HasColumnType("text"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/Models/Northwind.Mapping/CustomersMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class CustomersMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => e.CustomerId); 12 | 13 | builder.HasIndex(e => e.City) 14 | .HasDatabaseName("City"); 15 | 16 | builder.HasIndex(e => e.CompanyName) 17 | .HasDatabaseName("Customer_CompanyName"); 18 | 19 | builder.HasIndex(e => e.PostalCode) 20 | .HasDatabaseName("Customer_Postal_ode"); 21 | 22 | builder.HasIndex(e => e.Region) 23 | .HasDatabaseName("Customer_Region"); 24 | 25 | builder.Property(e => e.CustomerId) 26 | .HasColumnName("CustomerID") 27 | .HasMaxLength(5) 28 | .ValueGeneratedNever(); 29 | 30 | builder.Property(e => e.Address).HasMaxLength(60); 31 | builder.Property(e => e.City).HasMaxLength(15); 32 | builder.Property(e => e.CompanyName) 33 | .IsRequired() 34 | .HasMaxLength(40); 35 | 36 | builder.Property(e => e.ContactName).HasMaxLength(30); 37 | builder.Property(e => e.ContactTitle).HasMaxLength(30); 38 | builder.Property(e => e.Country).HasMaxLength(15); 39 | builder.Property(e => e.Fax).HasMaxLength(24); 40 | builder.Property(e => e.Phone).HasMaxLength(24); 41 | builder.Property(e => e.PostalCode).HasMaxLength(10); 42 | builder.Property(e => e.Region).HasMaxLength(15); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/Models/Northwind.Mapping/EmployeeTerritoriesMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping 6 | { 7 | public class EmployeeTerritoriesMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => new { e.EmployeeId, e.TerritoryId }); 12 | 13 | builder.Property(e => e.EmployeeId).HasColumnName("EmployeeID"); 14 | 15 | builder.Property(e => e.TerritoryId) 16 | .HasColumnName("TerritoryID") 17 | .HasMaxLength(20); 18 | 19 | builder.HasOne(d => d.Employee) 20 | .WithMany(p => p.EmployeeTerritories) 21 | .HasForeignKey(d => d.EmployeeId) 22 | .OnDelete(DeleteBehavior.ClientSetNull) 23 | .HasConstraintName("FK_EmployeeTerritories_Employees"); 24 | 25 | builder.HasOne(d => d.Territory) 26 | .WithMany(p => p.EmployeeTerritories) 27 | .HasForeignKey(d => d.TerritoryId) 28 | .OnDelete(DeleteBehavior.ClientSetNull) 29 | .HasConstraintName("FK_EmployeeTerritories_Territories"); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/Models/Northwind.Mapping/EmployeesMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping 6 | { 7 | public class EmployeesMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => e.EmployeeId); 12 | 13 | builder.HasIndex(e => e.LastName) 14 | .HasDatabaseName("Employee_LastName"); 15 | 16 | builder.HasIndex(e => e.PostalCode) 17 | .HasDatabaseName("Employee_PostalCode"); 18 | 19 | builder.Property(e => e.EmployeeId).HasColumnName("EmployeeID") 20 | .ValueGeneratedNever(); 21 | 22 | builder.Property(e => e.Address).HasMaxLength(60); 23 | 24 | builder.Property(e => e.BirthDate).HasColumnType("datetime"); 25 | 26 | builder.Property(e => e.City).HasMaxLength(15); 27 | 28 | builder.Property(e => e.Country).HasMaxLength(15); 29 | 30 | builder.Property(e => e.Extension).HasMaxLength(4); 31 | 32 | builder.Property(e => e.FirstName) 33 | .IsRequired() 34 | .HasMaxLength(10); 35 | 36 | builder.Property(e => e.HireDate).HasColumnType("datetime"); 37 | 38 | builder.Property(e => e.HomePhone).HasMaxLength(24); 39 | 40 | builder.Property(e => e.LastName) 41 | .IsRequired() 42 | .HasMaxLength(20); 43 | 44 | builder.Property(e => e.Notes).HasColumnType("text"); 45 | 46 | builder.Property(e => e.Photo).HasColumnType("blob"); 47 | 48 | builder.Property(e => e.PhotoPath).HasMaxLength(255); 49 | 50 | builder.Property(e => e.PostalCode).HasMaxLength(10); 51 | 52 | builder.Property(e => e.Region).HasMaxLength(15); 53 | 54 | builder.Property(e => e.Title).HasMaxLength(30); 55 | 56 | builder.Property(e => e.TitleOfCourtesy).HasMaxLength(25); 57 | 58 | builder.HasOne(d => d.ReportsToNavigation) 59 | .WithMany(p => p.InverseReportsToNavigation) 60 | .HasForeignKey(d => d.ReportsTo) 61 | .HasConstraintName("FK_Employees_Employees"); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/Models/Northwind.Mapping/OrderDetailsMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping 6 | { 7 | public class OrderDetailsMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => new { e.OrderId, e.ProductId }); 12 | 13 | builder.ToTable("Order Details"); 14 | 15 | builder.HasIndex(e => e.OrderId) 16 | .HasDatabaseName("OrdersOrder_Details"); 17 | 18 | builder.HasIndex(e => e.ProductId) 19 | .HasDatabaseName("ProductsOrder_Details"); 20 | 21 | builder.Property(e => e.OrderId).HasColumnName("OrderID"); 22 | 23 | builder.Property(e => e.ProductId).HasColumnName("ProductID"); 24 | 25 | builder.Property(e => e.Quantity).HasDefaultValue(1); 26 | 27 | builder.Property(e => e.UnitPrice).HasColumnType("decimal(13, 4)"); 28 | 29 | builder.HasOne(d => d.Order) 30 | .WithMany(p => p.OrderDetails) 31 | .HasForeignKey(d => d.OrderId) 32 | .OnDelete(DeleteBehavior.ClientSetNull) 33 | .HasConstraintName("FK_Order_Details_Orders"); 34 | 35 | builder.HasOne(d => d.Product) 36 | .WithMany(p => p.OrderDetails) 37 | .HasForeignKey(d => d.ProductId) 38 | .OnDelete(DeleteBehavior.ClientSetNull) 39 | .HasConstraintName("FK_Order_Details_Products"); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/Models/Northwind.Mapping/OrderMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping 6 | { 7 | public class OrderMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => e.OrderId); 12 | 13 | builder.HasIndex(e => e.CustomerId) 14 | .HasDatabaseName("Order_CustomersOrders"); 15 | 16 | builder.HasIndex(e => e.EmployeeId) 17 | .HasDatabaseName("Order_EmployeesOrders"); 18 | 19 | builder.HasIndex(e => e.OrderDate) 20 | .HasDatabaseName("Order_OrderDate"); 21 | 22 | builder.HasIndex(e => e.ShipPostalCode) 23 | .HasDatabaseName("Order_ShipPostalCode"); 24 | 25 | builder.HasIndex(e => e.ShipVia) 26 | .HasDatabaseName("Order_ShippersOrders"); 27 | 28 | builder.HasIndex(e => e.ShippedDate) 29 | .HasDatabaseName("Order_ShippedDate"); 30 | 31 | builder.Property(e => e.OrderId).HasColumnName("OrderID") 32 | .ValueGeneratedNever(); 33 | 34 | builder.Property(e => e.CustomerId) 35 | .HasColumnName("CustomerID") 36 | .HasMaxLength(5); 37 | 38 | builder.Property(e => e.EmployeeId).HasColumnName("EmployeeID"); 39 | 40 | builder.Property(e => e.Freight) 41 | .HasColumnType("decimal(13, 4)") 42 | .HasDefaultValue(0m); 43 | 44 | builder.Property(e => e.OrderDate).HasColumnType("datetime"); 45 | 46 | builder.Property(e => e.RequiredDate).HasColumnType("datetime"); 47 | 48 | builder.Property(e => e.ShipAddress).HasMaxLength(60); 49 | 50 | builder.Property(e => e.ShipCity).HasMaxLength(15); 51 | 52 | builder.Property(e => e.ShipCountry).HasMaxLength(15); 53 | 54 | builder.Property(e => e.ShipName).HasMaxLength(40); 55 | 56 | builder.Property(e => e.ShipPostalCode).HasMaxLength(10); 57 | 58 | builder.Property(e => e.ShipRegion).HasMaxLength(15); 59 | 60 | builder.Property(e => e.ShippedDate).HasColumnType("datetime"); 61 | 62 | builder.HasOne(d => d.Customer) 63 | .WithMany(p => p.Orders) 64 | .HasForeignKey(d => d.CustomerId) 65 | .HasConstraintName("FK_Orders_Customers"); 66 | 67 | builder.HasOne(d => d.Employee) 68 | .WithMany(p => p.Orders) 69 | .HasForeignKey(d => d.EmployeeId) 70 | .HasConstraintName("FK_Orders_Employees"); 71 | 72 | builder.HasOne(d => d.ShipViaNavigation) 73 | .WithMany(p => p.Orders) 74 | .HasForeignKey(d => d.ShipVia) 75 | .HasConstraintName("FK_Orders_Shippers"); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/Models/Northwind.Mapping/ProductsMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping 6 | { 7 | public class ProductsMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => e.ProductId); 12 | 13 | builder.HasIndex(e => e.CategoryId) 14 | .HasDatabaseName("Product_CategoryID"); 15 | 16 | builder.HasIndex(e => e.ProductName) 17 | .HasDatabaseName("Product_ProductName"); 18 | 19 | builder.HasIndex(e => e.SupplierId) 20 | .HasDatabaseName("Product_SuppliersProducts"); 21 | 22 | builder.Property(e => e.ProductId).HasColumnName("ProductID") 23 | .ValueGeneratedNever(); 24 | 25 | builder.Property(e => e.CategoryId).HasColumnName("CategoryID"); 26 | 27 | builder.Property(e => e.ProductName) 28 | .IsRequired() 29 | .HasMaxLength(40); 30 | 31 | builder.Property(e => e.QuantityPerUnit).HasMaxLength(20); 32 | 33 | builder.Property(e => e.ReorderLevel).HasDefaultValue((short)0); 34 | 35 | builder.Property(e => e.SupplierId).HasColumnName("SupplierID"); 36 | 37 | builder.Property(e => e.UnitPrice) 38 | .HasColumnType("decimal(13, 4)") 39 | .HasDefaultValue(0m); 40 | 41 | builder.Property(e => e.UnitsInStock).HasDefaultValue((short)0); 42 | 43 | builder.Property(e => e.UnitsOnOrder).HasDefaultValue((short)0); 44 | 45 | builder.HasOne(d => d.Category) 46 | .WithMany(p => p.Products) 47 | .HasForeignKey(d => d.CategoryId) 48 | .HasConstraintName("FK_Products_Categories"); 49 | 50 | builder.HasOne(d => d.Supplier) 51 | .WithMany(p => p.Products) 52 | .HasForeignKey(d => d.SupplierId) 53 | .HasConstraintName("FK_Products_Suppliers"); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/Models/Northwind.Mapping/RegionMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping 6 | { 7 | public class RegionMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => e.RegionId); 12 | 13 | builder.Property(e => e.RegionId) 14 | .HasColumnName("RegionID") 15 | .ValueGeneratedNever(); 16 | 17 | builder.Property(e => e.RegionDescription) 18 | .IsRequired() 19 | .HasMaxLength(50); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/Models/Northwind.Mapping/ShippersMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping 6 | { 7 | public class ShippersMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => e.ShipperId); 12 | 13 | builder.Property(e => e.ShipperId).HasColumnName("ShipperID") 14 | .ValueGeneratedNever(); 15 | 16 | builder.Property(e => e.CompanyName) 17 | .IsRequired() 18 | .HasMaxLength(40); 19 | 20 | builder.Property(e => e.Phone).HasMaxLength(24); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/Models/Northwind.Mapping/SuppliersMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping 6 | { 7 | public class SuppliersMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | 12 | builder.HasKey(e => e.SupplierId); 13 | 14 | builder.HasIndex(e => e.CompanyName) 15 | .HasDatabaseName("Supplier_CompanyName"); 16 | 17 | builder.HasIndex(e => e.PostalCode) 18 | .HasDatabaseName("Supplier_PostalCode"); 19 | 20 | builder.Property(e => e.SupplierId).HasColumnName("SupplierID") 21 | .ValueGeneratedNever(); 22 | 23 | builder.Property(e => e.Address).HasMaxLength(60); 24 | 25 | builder.Property(e => e.City).HasMaxLength(15); 26 | 27 | builder.Property(e => e.CompanyName) 28 | .IsRequired() 29 | .HasMaxLength(40); 30 | 31 | builder.Property(e => e.ContactName).HasMaxLength(30); 32 | 33 | builder.Property(e => e.ContactTitle).HasMaxLength(30); 34 | 35 | builder.Property(e => e.Country).HasMaxLength(15); 36 | 37 | builder.Property(e => e.Fax).HasMaxLength(24); 38 | 39 | builder.Property(e => e.HomePage).HasColumnType("text"); 40 | 41 | builder.Property(e => e.Phone).HasMaxLength(24); 42 | 43 | builder.Property(e => e.PostalCode).HasMaxLength(10); 44 | 45 | builder.Property(e => e.Region).HasMaxLength(15); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/Models/Northwind.Mapping/TerritoriesMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping 6 | { 7 | public class TerritoriesMap : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(e => e.TerritoryId); 12 | 13 | builder.Property(e => e.TerritoryId) 14 | .HasColumnName("TerritoryID") 15 | .HasMaxLength(20) 16 | .ValueGeneratedNever(); 17 | 18 | builder.Property(e => e.RegionId).HasColumnName("RegionID"); 19 | 20 | builder.Property(e => e.TerritoryDescription) 21 | .IsRequired() 22 | .HasMaxLength(50); 23 | 24 | builder.HasOne(d => d.Region) 25 | .WithMany(p => p.Territories) 26 | .HasForeignKey(d => d.RegionId) 27 | .OnDelete(DeleteBehavior.ClientSetNull) 28 | .HasConstraintName("FK_Territories_Region"); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/Models/Northwind/NorthwindContext.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping; 3 | using LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping; 4 | using Microsoft.EntityFrameworkCore; 5 | 6 | namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind 7 | { 8 | public class NorthwindContext : DbContext 9 | { 10 | public DbSet Categories { get; set; } = null!; 11 | public DbSet CustomerCustomerDemo { get; set; } = null!; 12 | public DbSet CustomerDemographics { get; set; } = null!; 13 | public DbSet Customers { get; set; } = null!; 14 | public DbSet Employees { get; set; } = null!; 15 | public DbSet EmployeeTerritories { get; set; } = null!; 16 | public DbSet OrderDetails { get; set; } = null!; 17 | public DbSet Orders { get; set; } = null!; 18 | public DbSet Products { get; set; } = null!; 19 | public DbSet Region { get; set; } = null!; 20 | public DbSet Shippers { get; set; } = null!; 21 | public DbSet Suppliers { get; set; } = null!; 22 | public DbSet Territories { get; set; } = null!; 23 | 24 | public NorthwindContext(DbContextOptions options) : base(options) 25 | { 26 | } 27 | 28 | protected override void OnModelCreating(ModelBuilder modelBuilder) 29 | { 30 | modelBuilder.ApplyConfiguration(new CategoriesMap()); 31 | modelBuilder.ApplyConfiguration(new CustomerCustomerDemoMap()); 32 | modelBuilder.ApplyConfiguration(new CustomerDemographicsMap()); 33 | modelBuilder.ApplyConfiguration(new CustomersMap()); 34 | modelBuilder.ApplyConfiguration(new EmployeesMap()); 35 | modelBuilder.ApplyConfiguration(new EmployeeTerritoriesMap()); 36 | modelBuilder.ApplyConfiguration(new OrderDetailsMap()); 37 | modelBuilder.ApplyConfiguration(new OrderMap()); 38 | modelBuilder.ApplyConfiguration(new ProductsMap()); 39 | modelBuilder.ApplyConfiguration(new RegionMap()); 40 | modelBuilder.ApplyConfiguration(new ShippersMap()); 41 | modelBuilder.ApplyConfiguration(new SuppliersMap()); 42 | modelBuilder.ApplyConfiguration(new TerritoriesMap()); 43 | 44 | modelBuilder.Entity() 45 | .HasQueryFilter(e => !IsFilterProducts || e.ProductId > 2); 46 | } 47 | 48 | public bool IsFilterProducts { get; set; } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SQLite.Tests/SQLiteTests.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using LinqToDB.Data; 3 | using LinqToDB.EntityFrameworkCore.BaseTests; 4 | using LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind; 5 | using Microsoft.EntityFrameworkCore; 6 | using NUnit.Framework; 7 | 8 | namespace LinqToDB.EntityFrameworkCore.SQLite.Tests 9 | { 10 | public class SQLiteTests : TestsBase 11 | { 12 | private DbContextOptions _options; 13 | 14 | static SQLiteTests() 15 | { 16 | LinqToDBForEFTools.Initialize(); 17 | DataConnection.TurnTraceSwitchOn(); 18 | } 19 | 20 | public SQLiteTests() 21 | { 22 | var optionsBuilder = new DbContextOptionsBuilder(); 23 | 24 | optionsBuilder.UseSqlite("Data Source=northwind.db;"); 25 | 26 | optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory); 27 | 28 | _options = optionsBuilder.Options; 29 | } 30 | 31 | private NorthwindContext CreateSQLiteSqlEntitiesContext() 32 | { 33 | var ctx = new NorthwindContext(_options); 34 | ctx.Database.EnsureDeleted(); 35 | ctx.Database.EnsureCreated(); 36 | return ctx; 37 | } 38 | 39 | [Test(Description = "https://github.com/linq2db/linq2db.EntityFrameworkCore/issues/343")] 40 | public void TestFunctionsMapping() 41 | { 42 | var optionsBuilder = new DbContextOptionsBuilder(); 43 | optionsBuilder.UseSqlite("Data Source=northwind.db;"); 44 | optionsBuilder.UseLinqToDB(x => x.AddCustomOptions(o => o.UseSQLiteMicrosoft())); 45 | optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory); 46 | 47 | using var ctx = new NorthwindContext(optionsBuilder.Options); 48 | ctx.Database.EnsureDeleted(); 49 | ctx.Database.EnsureCreated(); 50 | 51 | ctx.Categories.ToLinqToDB().ToList(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/ForMappingTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using FluentAssertions; 4 | using LinqToDB.DataProvider.SqlServer; 5 | using LinqToDB.EntityFrameworkCore.BaseTests; 6 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.ForMapping; 7 | using LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.ForMapping; 8 | using Microsoft.EntityFrameworkCore; 9 | using NUnit.Framework; 10 | 11 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests 12 | { 13 | [TestFixture] 14 | public class ForMappingTests : ForMappingTestsBase 15 | { 16 | private bool _isDbCreated; 17 | 18 | protected override ForMappingContextBase CreateContext(Func? optionsSetter = null) 19 | { 20 | var optionsBuilder = new DbContextOptionsBuilder(); 21 | optionsBuilder.UseSqlServer(Settings.ForMappingConnectionString); 22 | optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory); 23 | 24 | if (optionsSetter! != null) 25 | optionsBuilder.UseLinqToDB(builder => builder.AddCustomOptions(optionsSetter)); 26 | 27 | var options = optionsBuilder.Options; 28 | var ctx = new ForMappingContext(options); 29 | 30 | if (!_isDbCreated) 31 | { 32 | ctx.Database.EnsureDeleted(); 33 | ctx.Database.EnsureCreated(); 34 | 35 | _isDbCreated = true; 36 | } 37 | 38 | return ctx; 39 | } 40 | 41 | [Test] 42 | public void TestStringMappings() 43 | { 44 | using (var db = CreateContext()) 45 | { 46 | var ms = LinqToDBForEFTools.GetMappingSchema(db.Model, db, null); 47 | var ed = ms.GetEntityDescriptor(typeof(StringTypes)); 48 | 49 | ed.Columns.First(c => c.MemberName == nameof(StringTypes.AsciiString)).DataType.Should() 50 | .Be(DataType.VarChar); 51 | 52 | ed.Columns.First(c => c.MemberName == nameof(StringTypes.UnicodeString)).DataType.Should() 53 | .Be(DataType.NVarChar); 54 | } 55 | } 56 | 57 | [Test(Description = "https://github.com/linq2db/linq2db.EntityFrameworkCore/issues/349")] 58 | public void TestColumnLengthMappings() 59 | { 60 | using (var db = CreateContext()) 61 | { 62 | var ms = LinqToDBForEFTools.GetMappingSchema(db.Model, db, null); 63 | var ed = ms.GetEntityDescriptor(typeof(TypesTable)); 64 | 65 | ed.Columns.First(c => c.MemberName == nameof(TypesTable.DateTime)).Length.Should().BeNull(); 66 | ed.Columns.First(c => c.MemberName == nameof(TypesTable.String)).Length.Should().Be(100); 67 | } 68 | } 69 | 70 | [Test] 71 | public void TestDialectUse() 72 | { 73 | using var db = CreateContext(o => o.UseSqlServer("TODO:remove after fix from linq2db (not used)", SqlServerVersion.v2005)); 74 | using var dc = db.CreateLinqToDBConnectionDetached(); 75 | Assert.That(dc.MappingSchema.DisplayID, Does.Contain("2005")); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/IssueTests.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using System.Linq; 3 | using FluentAssertions; 4 | using LinqToDB.DataProvider.SqlServer; 5 | using LinqToDB.EntityFrameworkCore.BaseTests; 6 | using LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.IssueModel; 7 | using Microsoft.EntityFrameworkCore; 8 | using NUnit.Framework; 9 | 10 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests 11 | { 12 | [TestFixture] 13 | public class IssueTests : TestsBase 14 | { 15 | private DbContextOptions _options; 16 | private bool _created; 17 | 18 | public IssueTests() 19 | { 20 | InitOptions(); 21 | } 22 | 23 | [MemberNotNull(nameof(_options))] 24 | private void InitOptions() 25 | { 26 | var optionsBuilder = new DbContextOptionsBuilder(); 27 | 28 | optionsBuilder.UseSqlServer(Settings.IssuesConnectionString); 29 | optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory); 30 | 31 | _options = optionsBuilder.Options; 32 | } 33 | 34 | private IssueContext CreateContext() 35 | { 36 | var ctx = new IssueContext(_options); 37 | 38 | if (!_created) 39 | { 40 | //ctx.Database.EnsureDeleted(); 41 | ctx.Database.EnsureCreated(); 42 | _created = true; 43 | } 44 | 45 | return ctx; 46 | } 47 | 48 | 49 | [Test] 50 | public void Issue73Test() 51 | { 52 | using var ctx = CreateContext(); 53 | 54 | var q = ctx.Issue73Entities 55 | .Where(x => x.Name == "Name1_3") 56 | .Select(x => x.Parent!.Name + ">" + x.Name); 57 | 58 | var efItems = q.ToList(); 59 | var linq2dbItems = q.ToLinqToDB().ToList(); 60 | 61 | AreEqual(efItems, linq2dbItems); 62 | } 63 | 64 | [Test] 65 | public void Issue117Test() 66 | { 67 | using var ctx = CreateContext(); 68 | 69 | var userId = 1; 70 | 71 | var query = 72 | from p in ctx.Patents.Include(p => p.Assessment) 73 | where p.Assessment == null || (p.Assessment.TechnicalReviewerId != userId) 74 | select new { PatentId = p.Id, UserId = userId }; 75 | 76 | var resultEF = query.ToArray(); 77 | 78 | using var db = ctx.CreateLinqToDBConnection(); 79 | 80 | _ = query.ToLinqToDB(db).ToArray(); 81 | 82 | Assert.That(db.LastQuery, Does.Not.Contain("INNER")); 83 | } 84 | 85 | [Test] 86 | public void Issue321Test() 87 | { 88 | using var ctx = CreateContext(); 89 | 90 | var _ = ctx.Patents.AsSqlServer().ToLinqToDB().ToArray(); 91 | } 92 | 93 | [Test(Description = "https://github.com/linq2db/linq2db.EntityFrameworkCore/issues/345")] 94 | public void AsNoTrackingWithIdentityResolutionHandling() 95 | { 96 | using var ctx = CreateContext(); 97 | 98 | _ = ctx.Patents.AsNoTrackingWithIdentityResolution().ToLinqToDB().ToArray(); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/JsonConvertTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using LinqToDB.EntityFrameworkCore.BaseTests; 4 | using Microsoft.EntityFrameworkCore; 5 | using Microsoft.EntityFrameworkCore.Query; 6 | using Microsoft.EntityFrameworkCore.Query.SqlExpressions; 7 | using Newtonsoft.Json; 8 | using NUnit.Framework; 9 | 10 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests 11 | { 12 | [TestFixture] 13 | public class JsonConvertTests : TestsBase 14 | { 15 | private DbContextOptions _options; 16 | 17 | private sealed class LocalizedString 18 | { 19 | public string English { get; set; } = null!; 20 | public string German { get; set; } = null!; 21 | public string Slovak { get; set; } = null!; 22 | } 23 | 24 | private class EventScheduleItemBase 25 | { 26 | public int Id { get; set; } 27 | public virtual LocalizedString NameLocalized { get; set; } = null!; 28 | public virtual string? JsonColumn { get; set; } 29 | } 30 | 31 | #pragma warning disable CA1028 // Enum Storage should be Int32 32 | private enum CrashEnum : byte 33 | #pragma warning restore CA1028 // Enum Storage should be Int32 34 | { 35 | OneValue = 0, 36 | OtherValue = 1 37 | } 38 | 39 | private sealed class EventScheduleItem : EventScheduleItemBase 40 | { 41 | public CrashEnum CrashEnum { get; set; } 42 | public Guid GuidColumn { get; set; } 43 | } 44 | 45 | private sealed class JsonConvertContext : DbContext 46 | { 47 | public JsonConvertContext() 48 | { 49 | } 50 | 51 | public JsonConvertContext(DbContextOptions options) 52 | : base(options) 53 | { 54 | } 55 | 56 | public DbSet EventScheduleItems { get; set; } = null!; 57 | 58 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 59 | { 60 | if (!optionsBuilder.IsConfigured) optionsBuilder.UseSqlServer("conn string"); 61 | } 62 | 63 | protected override void OnModelCreating(ModelBuilder modelBuilder) 64 | { 65 | modelBuilder.Entity(entity => 66 | { 67 | entity.ToTable("EventScheduleItem"); 68 | entity.Property(e => e.NameLocalized) 69 | .HasColumnName("NameLocalized_JSON") 70 | .HasConversion(v => JsonConvert.SerializeObject(v), 71 | v => JsonConvert.DeserializeObject(v) ?? new()); 72 | entity.Property(e => e.CrashEnum).HasColumnType("tinyint"); 73 | entity.Property(e => e.GuidColumn).HasColumnType("uniqueidentifier"); 74 | }); 75 | 76 | modelBuilder.HasDbFunction(typeof(JsonConvertTests).GetMethod(nameof(JsonValue))!) 77 | .HasTranslation(e => new SqlFunctionExpression( 78 | "JSON_VALUE", e, true, e.Select(_ => false), typeof(string), null)); 79 | } 80 | } 81 | 82 | public JsonConvertTests() 83 | { 84 | var optionsBuilder = new DbContextOptionsBuilder(); 85 | //new SqlServerDbContextOptionsBuilder(optionsBuilder); 86 | 87 | optionsBuilder.UseSqlServer(Settings.JsonConvertConnectionString); 88 | optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory); 89 | 90 | _options = optionsBuilder.Options; 91 | } 92 | 93 | #pragma warning disable NUnit1028 // The non-test method is public 94 | public static string JsonValue(string? column, [NotParameterized] string path) 95 | #pragma warning restore NUnit1028 // The non-test method is public 96 | { 97 | throw new NotSupportedException(); 98 | } 99 | 100 | [Test] 101 | public void TestJsonConvert() 102 | { 103 | LinqToDBForEFTools.Initialize(); 104 | 105 | // // converting from string, because usually JSON is stored as string, but it depends on DataProvider 106 | // Mapping.MappingSchema.Default.SetConverter(v => JsonConvert.DeserializeObject(v)); 107 | // 108 | // // here we told linq2db how to pass converted value as DataParameter. 109 | // Mapping.MappingSchema.Default.SetConverter(v => new DataParameter("", JsonConvert.SerializeObject(v), LinqToDB.DataType.NVarChar)); 110 | 111 | using (var ctx = new JsonConvertContext(_options)) 112 | { 113 | ctx.Database.EnsureDeleted(); 114 | ctx.Database.EnsureCreated(); 115 | 116 | ctx.EventScheduleItems.Delete(); 117 | 118 | ctx.EventScheduleItems.Add(new EventScheduleItem() 119 | { 120 | NameLocalized = new LocalizedString() { English = "English", German = "German", Slovak = "Slovak" }, 121 | GuidColumn = Guid.NewGuid() 122 | }); 123 | ctx.SaveChanges(); 124 | 125 | var queryable = ctx.EventScheduleItems 126 | .Where(p => p.Id < 10).ToLinqToDB(); 127 | 128 | var path = "some"; 129 | 130 | var items = queryable 131 | .Select(p => new 132 | { 133 | p.Id, 134 | p.NameLocalized, 135 | p.CrashEnum, 136 | p.GuidColumn, 137 | JsonValue = JsonValue(p.JsonColumn, path) 138 | }); 139 | 140 | var item = items.FirstOrDefault(); 141 | 142 | Assert.That(item, Is.Not.Null); 143 | Assert.Multiple(() => 144 | { 145 | Assert.That(item!.NameLocalized.English, Is.EqualTo("English")); 146 | Assert.That(item.NameLocalized.German, Is.EqualTo("German")); 147 | Assert.That(item.NameLocalized.Slovak, Is.EqualTo("Slovak")); 148 | }); 149 | 150 | //TODO: make it work 151 | // var concrete = queryable.Select(p => new 152 | // { 153 | // p.Id, 154 | // English = p.NameLocalized.English 155 | // }).FirstOrDefault(); 156 | // 157 | // Assert.That(concrete.English, Is.EqualTo("English")); 158 | } 159 | } 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/ForMapping/ForMappingContext.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.ForMapping; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.ForMapping 5 | { 6 | public class ForMappingContext : ForMappingContextBase 7 | { 8 | public ForMappingContext(DbContextOptions options) : base(options) 9 | { 10 | } 11 | 12 | protected override void OnModelCreating(ModelBuilder modelBuilder) 13 | { 14 | modelBuilder.Entity(b => 15 | { 16 | b.HasKey(e => e.Id); 17 | 18 | b.Property(e => e.Id) 19 | .UseIdentityColumn(); 20 | }); 21 | 22 | modelBuilder.Entity(b => 23 | { 24 | b.HasKey(e => e.Id); 25 | }); 26 | 27 | modelBuilder.Entity(b => 28 | { 29 | b.Property(e => e.AsciiString).HasMaxLength(50).IsUnicode(false); 30 | b.Property(e => e.UnicodeString).HasMaxLength(50).IsUnicode(); 31 | } 32 | ); 33 | 34 | modelBuilder.Entity(b => 35 | { 36 | b.Property(e => e.DateTime); 37 | b.Property(e => e.String).HasMaxLength(100); 38 | }); 39 | 40 | modelBuilder.Entity(b => 41 | { 42 | b.HasDiscriminator(x => x.Discriminator); 43 | }); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Inheritance/InheritanceContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Inheritance 4 | { 5 | public abstract class BlogBase 6 | { 7 | public int Id { get; set; } 8 | public string BlogType { get; set; } = null!; 9 | } 10 | 11 | public class Blog : BlogBase 12 | { 13 | public string Url { get; set; } = null!; 14 | } 15 | 16 | public class RssBlog : BlogBase 17 | { 18 | public string Url { get; set; } = null!; 19 | } 20 | 21 | public abstract class ShadowBlogBase 22 | { 23 | public int Id { get; set; } 24 | public string BlogType { get; set; } = null!; 25 | } 26 | 27 | public class ShadowBlog : ShadowBlogBase 28 | { 29 | public string Url { get; set; } = null!; 30 | } 31 | 32 | public class ShadowRssBlog : ShadowBlogBase 33 | { 34 | public string Url { get; set; } = null!; 35 | } 36 | 37 | public class InheritanceContext : DbContext 38 | { 39 | public InheritanceContext(DbContextOptions options) : base(options) 40 | { 41 | 42 | } 43 | 44 | protected override void OnModelCreating(ModelBuilder modelBuilder) 45 | { 46 | modelBuilder.Entity() 47 | .HasDiscriminator(b => b.BlogType) 48 | .HasValue("blog_base") 49 | .HasValue("blog_rss"); 50 | 51 | modelBuilder.Entity() 52 | .Property(e => e.BlogType) 53 | .HasColumnName("BlogType") 54 | .HasMaxLength(200); 55 | 56 | modelBuilder.Entity() 57 | .Property(b => b.Url) 58 | .HasColumnName("Url"); 59 | 60 | modelBuilder.Entity() 61 | .Property(b => b.Url) 62 | .HasColumnName("Url"); 63 | 64 | modelBuilder.Entity().ToTable("Blogs"); 65 | modelBuilder.Entity().ToTable("Blogs"); 66 | 67 | ///// 68 | 69 | modelBuilder.Entity() 70 | .HasDiscriminator() 71 | .HasValue("blog_base") 72 | .HasValue("blog_rss"); 73 | 74 | modelBuilder.Entity() 75 | .Property(e => e.BlogType) 76 | .HasColumnName("BlogType") 77 | .HasMaxLength(200); 78 | 79 | modelBuilder.Entity() 80 | .Property(b => b.Url) 81 | .HasColumnName("Url"); 82 | 83 | modelBuilder.Entity() 84 | .Property(b => b.Url) 85 | .HasColumnName("Url"); 86 | 87 | modelBuilder.Entity().ToTable("ShadowBlogs"); 88 | modelBuilder.Entity().ToTable("ShadowBlogs"); 89 | } 90 | 91 | public DbSet Blogs { get; set; } = null!; 92 | public DbSet ShadowBlogs { get; set; } = null!; 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/IssueModel/Issue117Entities.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.IssueModel 4 | { 5 | public class Patent 6 | { 7 | [Key] 8 | public int Id { get; set; } 9 | public PatentAssessment? Assessment { get; set; } 10 | } 11 | 12 | public class PatentAssessment 13 | { 14 | [Key] 15 | public int PatentId { get; set; } 16 | public Patent Patent { get; set; } = null!; 17 | public int? TechnicalReviewerId { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/IssueModel/Issue73Entity.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.IssueModel 4 | { 5 | public sealed class Issue73Entity 6 | { 7 | public int Id { get; set; } 8 | 9 | public int? ParentId { get; set; } 10 | 11 | public Issue73Entity? Parent { get; set; } 12 | public List Childs { get; set; } = null!; 13 | 14 | public string Name { get; set; } = null!; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/IssueModel/IssueContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.IssueModel 4 | { 5 | public class IssueContext : DbContext 6 | { 7 | public DbSet Issue73Entities { get; set; } = null!; 8 | 9 | public DbSet Patents { get; set; } = null!; 10 | 11 | public IssueContext(DbContextOptions options) : base(options) 12 | { 13 | } 14 | 15 | protected override void OnModelCreating(ModelBuilder modelBuilder) 16 | { 17 | modelBuilder.Entity(b => 18 | { 19 | b.HasKey(x => new { x.Id }); 20 | 21 | b.HasOne(x => x.Parent) 22 | .WithMany(x => x.Childs) 23 | .HasForeignKey(x => new { x.ParentId }) 24 | .HasPrincipalKey(x => new { x.Id }); 25 | 26 | b.HasData( 27 | [ 28 | new Issue73Entity 29 | { 30 | Id = 2, 31 | Name = "Name1_2", 32 | }, 33 | new Issue73Entity 34 | { 35 | Id = 3, 36 | Name = "Name1_3", 37 | ParentId = 2 38 | }, 39 | ]); 40 | }); 41 | 42 | modelBuilder 43 | .Entity() 44 | .HasOne(p => p.Assessment) 45 | .WithOne(pa => pa.Patent) 46 | .HasForeignKey(pa => pa.PatentId) 47 | .OnDelete(DeleteBehavior.Restrict); 48 | 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Northwind.Mapping/BaseEntityMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class BaseEntityMap : IEntityTypeConfiguration 8 | where T: BaseEntity 9 | { 10 | public virtual void Configure(EntityTypeBuilder builder) 11 | { 12 | builder.Property(e => e.IsDeleted).HasDefaultValue(false); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Northwind.Mapping/CategoriesMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class CategoriesMap : BaseEntityMap 8 | { 9 | public override void Configure(EntityTypeBuilder builder) 10 | { 11 | base.Configure(builder); 12 | 13 | builder.HasKey(e => e.CategoryId); 14 | 15 | builder.HasIndex(e => e.CategoryName) 16 | .HasDatabaseName("CategoryName"); 17 | 18 | builder.Property(e => e.CategoryId).HasColumnName("CategoryID") 19 | .ValueGeneratedNever(); 20 | 21 | builder.Property(e => e.CategoryName) 22 | .IsRequired() 23 | .HasMaxLength(15); 24 | 25 | builder.Property(e => e.Description).HasColumnType("nvarchar(max)"); 26 | 27 | builder.Property(e => e.Picture).HasColumnType("varbinary(max)"); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Northwind.Mapping/CustomerCustomerDemoMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class CustomerCustomerDemoMap : BaseEntityMap 8 | { 9 | public override void Configure(EntityTypeBuilder builder) 10 | { 11 | base.Configure(builder); 12 | 13 | builder.HasKey(e => new { e.CustomerId, e.CustomerTypeId }) 14 | .IsClustered(false); 15 | 16 | builder.Property(e => e.CustomerId) 17 | .HasColumnName("CustomerID") 18 | .HasMaxLength(5); 19 | 20 | builder.Property(e => e.CustomerTypeId) 21 | .HasColumnName("CustomerTypeID") 22 | .HasMaxLength(10); 23 | 24 | builder.HasOne(d => d.Customer) 25 | .WithMany(p => p.CustomerCustomerDemo) 26 | .HasForeignKey(d => d.CustomerId) 27 | .OnDelete(DeleteBehavior.ClientSetNull) 28 | .HasConstraintName("FK_CustomerCustomerDemo_Customers"); 29 | 30 | builder.HasOne(d => d.CustomerType) 31 | .WithMany(p => p.CustomerCustomerDemo) 32 | .HasForeignKey(d => d.CustomerTypeId) 33 | .OnDelete(DeleteBehavior.ClientSetNull) 34 | .HasConstraintName("FK_CustomerCustomerDemo"); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Northwind.Mapping/CustomerDemographicsMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class CustomerDemographicsMap : BaseEntityMap 8 | { 9 | public override void Configure(EntityTypeBuilder builder) 10 | { 11 | base.Configure(builder); 12 | 13 | builder.HasKey(e => e.CustomerTypeId) 14 | .IsClustered(false); 15 | 16 | builder.Property(e => e.CustomerTypeId) 17 | .HasColumnName("CustomerTypeID") 18 | .HasMaxLength(10) 19 | .ValueGeneratedNever(); 20 | 21 | builder.Property(e => e.CustomerDesc).HasColumnType("nvarchar(max)"); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Northwind.Mapping/CustomersMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class CustomersMap : BaseEntityMap 8 | { 9 | public override void Configure(EntityTypeBuilder builder) 10 | { 11 | base.Configure(builder); 12 | 13 | builder.HasKey(e => e.CustomerId); 14 | 15 | builder.HasIndex(e => e.City) 16 | .HasDatabaseName("City"); 17 | 18 | builder.HasIndex(e => e.CompanyName) 19 | .HasDatabaseName("CompanyName"); 20 | 21 | builder.HasIndex(e => e.PostalCode) 22 | .HasDatabaseName("PostalCode"); 23 | 24 | builder.HasIndex(e => e.Region) 25 | .HasDatabaseName("Region"); 26 | 27 | builder.Property(e => e.CustomerId) 28 | .HasColumnName("CustomerID") 29 | .HasMaxLength(5) 30 | .ValueGeneratedNever(); 31 | 32 | builder.Property(e => e.Address).HasMaxLength(60); 33 | builder.Property(e => e.City).HasMaxLength(15); 34 | builder.Property(e => e.CompanyName) 35 | .IsRequired() 36 | .HasMaxLength(40); 37 | 38 | builder.Property(e => e.ContactName).HasMaxLength(30); 39 | builder.Property(e => e.ContactTitle).HasMaxLength(30); 40 | builder.Property(e => e.Country).HasMaxLength(15); 41 | builder.Property(e => e.Fax).HasMaxLength(24); 42 | builder.Property(e => e.Phone).HasMaxLength(24); 43 | builder.Property(e => e.PostalCode).HasMaxLength(10); 44 | builder.Property(e => e.Region).HasMaxLength(15); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Northwind.Mapping/EmployeeTerritoriesMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class EmployeeTerritoriesMap : BaseEntityMap 8 | { 9 | public override void Configure(EntityTypeBuilder builder) 10 | { 11 | base.Configure(builder); 12 | 13 | builder.HasKey(e => new { e.EmployeeId, e.TerritoryId }) 14 | .IsClustered(false); 15 | 16 | builder.Property(e => e.EmployeeId).HasColumnName("EmployeeID"); 17 | 18 | builder.Property(e => e.TerritoryId) 19 | .HasColumnName("TerritoryID") 20 | .HasMaxLength(20); 21 | 22 | builder.HasOne(d => d.Employee) 23 | .WithMany(p => p.EmployeeTerritories) 24 | .HasForeignKey(d => d.EmployeeId) 25 | .OnDelete(DeleteBehavior.ClientSetNull) 26 | .HasConstraintName("FK_EmployeeTerritories_Employees"); 27 | 28 | builder.HasOne(d => d.Territory) 29 | .WithMany(p => p.EmployeeTerritories) 30 | .HasForeignKey(d => d.TerritoryId) 31 | .OnDelete(DeleteBehavior.ClientSetNull) 32 | .HasConstraintName("FK_EmployeeTerritories_Territories"); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Northwind.Mapping/EmployeesMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class EmployeesMap : BaseEntityMap 8 | { 9 | public override void Configure(EntityTypeBuilder builder) 10 | { 11 | base.Configure(builder); 12 | 13 | builder.HasKey(e => e.EmployeeId); 14 | 15 | builder.HasIndex(e => e.LastName) 16 | .HasDatabaseName("LastName"); 17 | 18 | builder.HasIndex(e => e.PostalCode) 19 | .HasDatabaseName("PostalCode"); 20 | 21 | builder.Property(e => e.EmployeeId).HasColumnName("EmployeeID") 22 | .ValueGeneratedNever(); 23 | 24 | builder.Property(e => e.Address).HasMaxLength(60); 25 | 26 | builder.Property(e => e.BirthDate).HasColumnType("datetime"); 27 | 28 | builder.Property(e => e.City).HasMaxLength(15); 29 | 30 | builder.Property(e => e.Country).HasMaxLength(15); 31 | 32 | builder.Property(e => e.Extension).HasMaxLength(4); 33 | 34 | builder.Property(e => e.FirstName) 35 | .IsRequired() 36 | .HasMaxLength(10); 37 | 38 | builder.Property(e => e.HireDate).HasColumnType("datetime"); 39 | 40 | builder.Property(e => e.HomePhone).HasMaxLength(24); 41 | 42 | builder.Property(e => e.LastName) 43 | .IsRequired() 44 | .HasMaxLength(20); 45 | 46 | builder.Property(e => e.Notes).HasColumnType("nvarchar(max)"); 47 | 48 | builder.Property(e => e.Photo).HasColumnType("varbinary(max)"); 49 | 50 | builder.Property(e => e.PhotoPath).HasMaxLength(255); 51 | 52 | builder.Property(e => e.PostalCode).HasMaxLength(10); 53 | 54 | builder.Property(e => e.Region).HasMaxLength(15); 55 | 56 | builder.Property(e => e.Title).HasMaxLength(30); 57 | 58 | builder.Property(e => e.TitleOfCourtesy).HasMaxLength(25); 59 | 60 | builder.HasOne(d => d.ReportsToNavigation) 61 | .WithMany(p => p.InverseReportsToNavigation) 62 | .HasForeignKey(d => d.ReportsTo) 63 | .HasConstraintName("FK_Employees_Employees"); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Northwind.Mapping/OrderDetailsMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class OrderDetailsMap : BaseEntityMap 8 | { 9 | public override void Configure(EntityTypeBuilder builder) 10 | { 11 | base.Configure(builder); 12 | 13 | builder.HasKey(e => new { e.OrderId, e.ProductId }); 14 | 15 | builder.ToTable("Order Details"); 16 | 17 | builder.HasIndex(e => e.OrderId) 18 | .HasDatabaseName("OrdersOrder_Details"); 19 | 20 | builder.HasIndex(e => e.ProductId) 21 | .HasDatabaseName("ProductsOrder_Details"); 22 | 23 | builder.Property(e => e.OrderId).HasColumnName("OrderID"); 24 | 25 | builder.Property(e => e.ProductId).HasColumnName("ProductID"); 26 | 27 | builder.Property(e => e.Quantity).HasDefaultValueSql("((1))"); 28 | 29 | builder.Property(e => e.UnitPrice).HasColumnType("money"); 30 | 31 | builder.HasOne(d => d.Order) 32 | .WithMany(p => p.OrderDetails) 33 | .HasForeignKey(d => d.OrderId) 34 | .OnDelete(DeleteBehavior.ClientSetNull) 35 | .HasConstraintName("FK_Order_Details_Orders"); 36 | 37 | builder.HasOne(d => d.Product) 38 | .WithMany(p => p.OrderDetails) 39 | .HasForeignKey(d => d.ProductId) 40 | .OnDelete(DeleteBehavior.ClientSetNull) 41 | .HasConstraintName("FK_Order_Details_Products"); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Northwind.Mapping/OrderMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class OrderMap : BaseEntityMap 8 | { 9 | public override void Configure(EntityTypeBuilder builder) 10 | { 11 | 12 | base.Configure(builder); 13 | 14 | builder.HasKey(e => e.OrderId); 15 | 16 | builder.HasIndex(e => e.CustomerId) 17 | .HasDatabaseName("CustomersOrders"); 18 | 19 | builder.HasIndex(e => e.EmployeeId) 20 | .HasDatabaseName("EmployeesOrders"); 21 | 22 | builder.HasIndex(e => e.OrderDate) 23 | .HasDatabaseName("OrderDate"); 24 | 25 | builder.HasIndex(e => e.ShipPostalCode) 26 | .HasDatabaseName("ShipPostalCode"); 27 | 28 | builder.HasIndex(e => e.ShipVia) 29 | .HasDatabaseName("ShippersOrders"); 30 | 31 | builder.HasIndex(e => e.ShippedDate) 32 | .HasDatabaseName("ShippedDate"); 33 | 34 | builder.Property(e => e.OrderId).HasColumnName("OrderID") 35 | .ValueGeneratedNever(); 36 | 37 | builder.Property(e => e.CustomerId) 38 | .HasColumnName("CustomerID") 39 | .HasMaxLength(5); 40 | 41 | builder.Property(e => e.EmployeeId).HasColumnName("EmployeeID"); 42 | 43 | builder.Property(e => e.Freight) 44 | .HasColumnType("money") 45 | .HasDefaultValueSql("((0))"); 46 | 47 | builder.Property(e => e.OrderDate).HasColumnType("datetime"); 48 | 49 | builder.Property(e => e.RequiredDate).HasColumnType("datetime"); 50 | 51 | builder.Property(e => e.ShipAddress).HasMaxLength(60); 52 | 53 | builder.Property(e => e.ShipCity).HasMaxLength(15); 54 | 55 | builder.Property(e => e.ShipCountry).HasMaxLength(15); 56 | 57 | builder.Property(e => e.ShipName).HasMaxLength(40); 58 | 59 | builder.Property(e => e.ShipPostalCode).HasMaxLength(10); 60 | 61 | builder.Property(e => e.ShipRegion).HasMaxLength(15); 62 | 63 | builder.Property(e => e.ShippedDate).HasColumnType("datetime"); 64 | 65 | builder.HasOne(d => d.Customer) 66 | .WithMany(p => p.Orders) 67 | .HasForeignKey(d => d.CustomerId) 68 | .HasConstraintName("FK_Orders_Customers"); 69 | 70 | builder.HasOne(d => d.Employee) 71 | .WithMany(p => p.Orders) 72 | .HasForeignKey(d => d.EmployeeId) 73 | .HasConstraintName("FK_Orders_Employees"); 74 | 75 | builder.HasOne(d => d.ShipViaNavigation) 76 | .WithMany(p => p.Orders) 77 | .HasForeignKey(d => d.ShipVia) 78 | .HasConstraintName("FK_Orders_Shippers"); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Northwind.Mapping/ProductsMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class ProductsMap : BaseEntityMap 8 | { 9 | public override void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.ToTable(t => t.IsTemporal()); 12 | 13 | builder.HasKey(e => e.ProductId); 14 | 15 | builder.HasIndex(e => e.CategoryId) 16 | .HasDatabaseName("CategoryID"); 17 | 18 | builder.HasIndex(e => e.ProductName) 19 | .HasDatabaseName("ProductName"); 20 | 21 | builder.HasIndex(e => e.SupplierId) 22 | .HasDatabaseName("SuppliersProducts"); 23 | 24 | builder.Property(e => e.ProductId).HasColumnName("ProductID") 25 | .ValueGeneratedNever(); 26 | 27 | builder.Property(e => e.CategoryId).HasColumnName("CategoryID"); 28 | 29 | builder.Property(e => e.ProductName) 30 | .IsRequired() 31 | .HasMaxLength(40); 32 | 33 | builder.Property(e => e.QuantityPerUnit).HasMaxLength(20); 34 | 35 | builder.Property(e => e.ReorderLevel).HasDefaultValueSql("((0))"); 36 | 37 | builder.Property(e => e.SupplierId).HasColumnName("SupplierID"); 38 | 39 | builder.Property(e => e.UnitPrice) 40 | .HasColumnType("money") 41 | .HasDefaultValueSql("((0))"); 42 | 43 | builder.Property(e => e.UnitsInStock).HasDefaultValueSql("((0))"); 44 | 45 | builder.Property(e => e.UnitsOnOrder).HasDefaultValueSql("((0))"); 46 | 47 | builder.HasOne(d => d.Category) 48 | .WithMany(p => p.Products) 49 | .HasForeignKey(d => d.CategoryId) 50 | .HasConstraintName("FK_Products_Categories"); 51 | 52 | builder.HasOne(d => d.Supplier) 53 | .WithMany(p => p.Products) 54 | .HasForeignKey(d => d.SupplierId) 55 | .HasConstraintName("FK_Products_Suppliers"); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Northwind.Mapping/RegionMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class RegionMap : BaseEntityMap 8 | { 9 | public override void Configure(EntityTypeBuilder builder) 10 | { 11 | base.Configure(builder); 12 | 13 | builder.HasKey(e => e.RegionId) 14 | .IsClustered(false); 15 | 16 | builder.Property(e => e.RegionId) 17 | .HasColumnName("RegionID") 18 | .ValueGeneratedNever(); 19 | 20 | builder.Property(e => e.RegionDescription) 21 | .IsRequired() 22 | .HasMaxLength(50); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Northwind.Mapping/ShippersMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class ShippersMap : BaseEntityMap 8 | { 9 | public override void Configure(EntityTypeBuilder builder) 10 | { 11 | base.Configure(builder); 12 | 13 | builder.HasKey(e => e.ShipperId); 14 | 15 | builder.Property(e => e.ShipperId).HasColumnName("ShipperID") 16 | .ValueGeneratedNever(); 17 | 18 | builder.Property(e => e.CompanyName) 19 | .IsRequired() 20 | .HasMaxLength(40); 21 | 22 | builder.Property(e => e.Phone).HasMaxLength(24); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Northwind.Mapping/SuppliersMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class SuppliersMap : BaseEntityMap 8 | { 9 | public override void Configure(EntityTypeBuilder builder) 10 | { 11 | base.Configure(builder); 12 | 13 | builder.HasKey(e => e.SupplierId); 14 | 15 | builder.HasIndex(e => e.CompanyName) 16 | .HasDatabaseName("CompanyName"); 17 | 18 | builder.HasIndex(e => e.PostalCode) 19 | .HasDatabaseName("PostalCode"); 20 | 21 | builder.Property(e => e.SupplierId).HasColumnName("SupplierID") 22 | .ValueGeneratedNever(); 23 | 24 | builder.Property(e => e.Address).HasMaxLength(60); 25 | 26 | builder.Property(e => e.City).HasMaxLength(15); 27 | 28 | builder.Property(e => e.CompanyName) 29 | .IsRequired() 30 | .HasMaxLength(40); 31 | 32 | builder.Property(e => e.ContactName).HasMaxLength(30); 33 | 34 | builder.Property(e => e.ContactTitle).HasMaxLength(30); 35 | 36 | builder.Property(e => e.Country).HasMaxLength(15); 37 | 38 | builder.Property(e => e.Fax).HasMaxLength(24); 39 | 40 | builder.Property(e => e.HomePage).HasColumnType("nvarchar(max)"); 41 | 42 | builder.Property(e => e.Phone).HasMaxLength(24); 43 | 44 | builder.Property(e => e.PostalCode).HasMaxLength(10); 45 | 46 | builder.Property(e => e.Region).HasMaxLength(15); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Northwind.Mapping/TerritoriesMap.cs: -------------------------------------------------------------------------------- 1 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping 6 | { 7 | public class TerritoriesMap : BaseEntityMap 8 | { 9 | public override void Configure(EntityTypeBuilder builder) 10 | { 11 | base.Configure(builder); 12 | 13 | builder.HasKey(e => e.TerritoryId) 14 | .IsClustered(false); 15 | 16 | builder.Property(e => e.TerritoryId) 17 | .HasColumnName("TerritoryID") 18 | .HasMaxLength(20) 19 | .ValueGeneratedNever(); 20 | 21 | builder.Property(e => e.RegionId).HasColumnName("RegionID"); 22 | 23 | builder.Property(e => e.TerritoryDescription) 24 | .IsRequired() 25 | .HasMaxLength(50); 26 | 27 | builder.HasOne(d => d.Region) 28 | .WithMany(p => p.Territories) 29 | .HasForeignKey(d => d.RegionId) 30 | .OnDelete(DeleteBehavior.ClientSetNull) 31 | .HasConstraintName("FK_Territories_Region"); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Northwind/NorthwindContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind; 4 | using LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping; 5 | using LinqToDB.Expressions; 6 | using LinqToDB.Extensions; 7 | using Microsoft.EntityFrameworkCore; 8 | 9 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind 10 | { 11 | public class NorthwindContext : DbContext 12 | { 13 | public DbSet Categories { get; set; } = null!; 14 | public DbSet CustomerCustomerDemo { get; set; } = null!; 15 | public DbSet CustomerDemographics { get; set; } = null!; 16 | public DbSet Customers { get; set; } = null!; 17 | public DbSet Employees { get; set; } = null!; 18 | public DbSet EmployeeTerritories { get; set; } = null!; 19 | public DbSet OrderDetails { get; set; } = null!; 20 | public DbSet Orders { get; set; } = null!; 21 | public DbSet Products { get; set; } = null!; 22 | public DbSet Region { get; set; } = null!; 23 | public DbSet Shippers { get; set; } = null!; 24 | public DbSet Suppliers { get; set; } = null!; 25 | public DbSet Territories { get; set; } = null!; 26 | 27 | public NorthwindContext(DbContextOptions options) : base(options) 28 | { 29 | 30 | } 31 | 32 | [DbFunction("ProcessLong", "dbo")] 33 | public static int ProcessLong(int seconds) 34 | { 35 | throw new NotImplementedException(); 36 | } 37 | 38 | protected override void OnModelCreating(ModelBuilder modelBuilder) 39 | { 40 | modelBuilder.ApplyConfiguration(new CategoriesMap()); 41 | modelBuilder.ApplyConfiguration(new CustomerCustomerDemoMap()); 42 | modelBuilder.ApplyConfiguration(new CustomerDemographicsMap()); 43 | modelBuilder.ApplyConfiguration(new CustomersMap()); 44 | modelBuilder.ApplyConfiguration(new EmployeesMap()); 45 | modelBuilder.ApplyConfiguration(new EmployeeTerritoriesMap()); 46 | modelBuilder.ApplyConfiguration(new OrderDetailsMap()); 47 | modelBuilder.ApplyConfiguration(new OrderMap()); 48 | modelBuilder.ApplyConfiguration(new ProductsMap()); 49 | modelBuilder.ApplyConfiguration(new RegionMap()); 50 | modelBuilder.ApplyConfiguration(new ShippersMap()); 51 | modelBuilder.ApplyConfiguration(new SuppliersMap()); 52 | modelBuilder.ApplyConfiguration(new TerritoriesMap()); 53 | 54 | modelBuilder.Entity() 55 | .HasQueryFilter(e => !IsFilterProducts || e.ProductId > 2); 56 | 57 | ConfigureGlobalQueryFilters(modelBuilder); 58 | } 59 | 60 | private void ConfigureGlobalQueryFilters(ModelBuilder builder) 61 | { 62 | foreach (var entityType in builder.Model.GetEntityTypes()) 63 | { 64 | if (typeof(ISoftDelete).IsSameOrParentOf(entityType.ClrType)) 65 | { 66 | var method = ConfigureEntityFilterMethodInfo.MakeGenericMethod(entityType.ClrType); 67 | method.Invoke(this, [builder]); 68 | } 69 | } 70 | } 71 | 72 | private static readonly MethodInfo ConfigureEntityFilterMethodInfo = 73 | MemberHelper.MethodOf(() => ((NorthwindContext)null!).ConfigureEntityFilter(null!)).GetGenericMethodDefinition(); 74 | 75 | public void ConfigureEntityFilter(ModelBuilder builder) 76 | where TEntity: class, ISoftDelete 77 | { 78 | NorthwindContext? obj = null; 79 | 80 | builder.Entity().HasQueryFilter(e => !obj!.IsSoftDeleteFilterEnabled || !e.IsDeleted || !EF.Property(e, "IsDeleted")); 81 | } 82 | 83 | public bool IsFilterProducts { get; set; } 84 | 85 | public bool IsSoftDeleteFilterEnabled { get; set; } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Settings.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests 2 | { 3 | public static class Settings 4 | { 5 | public const string ForMappingConnectionString = "Server=.;Database=ForMapping;Integrated Security=SSPI;Encrypt=true;TrustServerCertificate=true"; 6 | public const string IssuesConnectionString = "Server=.;Database=IssuesEFCore;Integrated Security=SSPI;Encrypt=true;TrustServerCertificate=true"; 7 | public const string JsonConvertConnectionString = "Server=.;Database=JsonConvertContext;Integrated Security=SSPI;Encrypt=true;TrustServerCertificate=true"; 8 | public const string NorthwindConnectionString = "Server=.;Database=NorthwindEFCore;Integrated Security=SSPI;Encrypt=true;TrustServerCertificate=true"; 9 | public const string ConverterConnectionString = "Server=.;Database=ConverterTests;Integrated Security=SSPI;Encrypt=true;TrustServerCertificate=true"; 10 | public const string InheritanceConnectionString = "Server=.;Database=InheritanceEFCore;Integrated Security=SSPI;Encrypt=true;TrustServerCertificate=true"; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/ValueConversion/ConvertorTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | using System.Linq; 4 | using LinqToDB.EntityFrameworkCore.BaseTests; 5 | using Microsoft.EntityFrameworkCore; 6 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 7 | using NUnit.Framework; 8 | 9 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.ValueConversion 10 | { 11 | [TestFixture] 12 | public class ConvertorTests 13 | { 14 | private DbContextOptions _options; 15 | 16 | private sealed class ConvertorContext : DbContext 17 | { 18 | public ConvertorContext(DbContextOptions options) : base(options) 19 | { 20 | } 21 | 22 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 23 | public DbSet Subdivisions { get; set; } = null!; 24 | } 25 | 26 | public ConvertorTests() 27 | { 28 | var optionsBuilder = new DbContextOptionsBuilder(); 29 | 30 | optionsBuilder 31 | .ReplaceService() 32 | .UseSqlServer(Settings.ConverterConnectionString) 33 | .UseLoggerFactory(TestUtils.LoggerFactory);; 34 | 35 | _options = optionsBuilder.Options; 36 | } 37 | 38 | 39 | [Test] 40 | public void TestToList() 41 | { 42 | using (var ctx = new ConvertorContext(_options)) 43 | using (var db = ctx.CreateLinqToDBConnection()) 44 | { 45 | ctx.Database.EnsureDeleted(); 46 | ctx.Database.EnsureCreated(); 47 | 48 | 49 | var result = db.InsertWithInt64Identity(new SubDivision() 50 | { Code = "C1", Id = new Id(0), Name = "N1", PermanentId = Guid.NewGuid() }); 51 | 52 | result = db.InsertWithInt64Identity(new SubDivision() 53 | { Code = "C2", Id = new Id(1), Name = "N2", PermanentId = Guid.NewGuid() }); 54 | 55 | result = db.InsertWithInt64Identity(new SubDivision() 56 | { Code = "C3", Id = new Id(2), Name = "N3", PermanentId = Guid.NewGuid() }); 57 | 58 | var ef = ctx.Subdivisions.Where(s => s.Id == 1L).ToArray(); 59 | var result1 = ctx.Subdivisions.ToLinqToDB().Where(s => s.Id == 1L).ToArray(); 60 | 61 | var id = new Id?(0L.AsId()); 62 | var result2 = ctx.Subdivisions.ToLinqToDB().Where(s => s.Id == id).ToArray(); 63 | 64 | var ids = new[] {1L.AsId(), 2L.AsId(),}; 65 | _ = ctx.Subdivisions.ToLinqToDB().Where(s => ids.Contains(s.Id)).ToArray(); 66 | 67 | _ = ctx.Subdivisions.ToLinqToDB().ToArray(); 68 | 69 | Assert.Multiple(() => 70 | { 71 | Assert.That(result1[0].Code, Is.EqualTo(ef[0].Code)); 72 | Assert.That(result1[0].Id, Is.EqualTo(ef[0].Id)); 73 | 74 | Assert.That(result2[0].Code, Is.EqualTo(ef[0].Code)); 75 | Assert.That(result2[0].Id, Is.EqualTo(ef[0].Id)); 76 | }); 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/ValueConversion/IEntity`1.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.ValueConversion 2 | { 3 | public interface IEntity 4 | { 5 | public TKey Id { get; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/ValueConversion/IdValueConverterSelector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.CodeAnalysis; 4 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 5 | 6 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.ValueConversion 7 | { 8 | public sealed class IdValueConverterSelector : ValueConverterSelector 9 | { 10 | public IdValueConverterSelector(ValueConverterSelectorDependencies dependencies) : base(dependencies) 11 | { 12 | } 13 | 14 | public override IEnumerable Select(Type modelClrType, Type? providerClrType = null) 15 | { 16 | var baseConverters = base.Select(modelClrType, providerClrType); 17 | foreach (var converter in baseConverters) 18 | yield return converter; 19 | 20 | modelClrType = Unwrap(modelClrType); 21 | providerClrType = Unwrap(providerClrType); 22 | 23 | if (!modelClrType.IsGenericType) 24 | yield break; 25 | 26 | if (modelClrType.GetGenericTypeDefinition() != typeof(Id<,>)) 27 | yield break; 28 | 29 | var t = modelClrType.GetGenericArguments(); 30 | var key = t[1]; 31 | providerClrType ??= key; 32 | if (key != providerClrType) 33 | yield break; 34 | 35 | var ct = 36 | 37 | key == typeof(long) 38 | ? typeof(IdValueConverter<>).MakeGenericType(t[0]) 39 | : 40 | 41 | typeof(IdValueConverter<,>).MakeGenericType(key, t[0]); 42 | yield return new ValueConverterInfo 43 | ( 44 | modelClrType, 45 | providerClrType, 46 | i => (ValueConverter)Activator.CreateInstance(ct, i.MappingHints)! 47 | ); 48 | 49 | [return: NotNullIfNotNull(nameof(type))] 50 | static Type? Unwrap(Type? type) => type == null ? null : Nullable.GetUnderlyingType(type) ?? type; 51 | } 52 | }} 53 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/ValueConversion/IdValueConverter`2.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.ValueConversion 4 | { 5 | public sealed class IdValueConverter : ValueConverter, TKey> 6 | where TEntity : IEntity 7 | where TKey : notnull 8 | { 9 | public IdValueConverter(ConverterMappingHints? mappingHints = null) 10 | : base(id => id.Value, key => new Id(key)) { } 11 | } 12 | 13 | public sealed class IdValueConverter : ValueConverter, long> 14 | where TEntity : IEntity 15 | { 16 | public IdValueConverter(ConverterMappingHints? mappingHints = null) 17 | : base(id => id.Value + 1, key => new Id(key - 1)) { } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/ValueConversion/Id`2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.ValueConversion 5 | { 6 | public static class Id 7 | { 8 | public static Id AsId(this long id) where T : IEntity => id.AsId(); 9 | 10 | public static Id AsId(this Guid guid) where T : IEntity => guid.AsId(); 11 | 12 | public static Id AsId(this TKey @object) 13 | where TEntity : IEntity 14 | where TKey : notnull 15 | => new(@object); 16 | } 17 | 18 | public readonly struct Id : IEquatable> where TEntity : IEntity 19 | where TKey: notnull 20 | { 21 | internal Id(TKey id) => Value = id; 22 | internal TKey Value { get; } 23 | public static implicit operator TKey(Id id) => id.Value; 24 | public override string ToString() => $"{typeof(TEntity).Name}({Value})"; 25 | public bool Equals(Id other) => EqualityComparer.Default.Equals(Value, other.Value); 26 | public override bool Equals(object? obj) => obj is Id other && Equals(other); 27 | public override int GetHashCode() => EqualityComparer.Default.GetHashCode(Value); 28 | public static bool operator == (Id left, Id right) 29 | => EqualityComparer.Default.Equals(left.Value, right.Value); 30 | public static bool operator != (Id left, Id right) => !(left == right); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/ValueConversion/SubDivision.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.ValueConversion 4 | { 5 | public class SubDivision : IEntity 6 | { 7 | long IEntity.Id => Id; 8 | public Id Id { get; set; } 9 | public Guid PermanentId { get; set; } 10 | public string Code { get; set; } = null!; 11 | public string Name { get; set; } = null!; 12 | public bool? IsDeleted { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | solution: 'linq2db.EFCore.sln' 3 | build_configuration: 'Release' 4 | assemblyVersion: 9.0.0 5 | nugetVersion: 9.0.0 6 | artifact_nugets: 'nugets' 7 | 8 | # build on commits to important branches (master + release branches): 9 | trigger: 10 | - master 11 | - release 12 | # don't trigger pr builds by default, users should trigger them manually using /azp bot commands 13 | # when we have multiple test runs waiting for free job, when nobody needs them 14 | # we only want to trigger it for pr to release branch 15 | pr: 16 | - master 17 | 18 | stages: 19 | 20 | ############################# 21 | # Build and publish nugets # 22 | ############################# 23 | - stage: '' 24 | displayName: '' 25 | jobs: 26 | - job: build_job 27 | pool: 28 | vmImage: 'windows-2022' 29 | variables: 30 | packageVersion: $(nugetVersion) 31 | displayName: 'Build' 32 | 33 | steps: 34 | 35 | 36 | - task: UseDotNet@2 37 | displayName: 'Install .NET 9' 38 | inputs: 39 | includePreviewVersions: true 40 | version: 9.x 41 | 42 | - task: PowerShell@2 43 | inputs: 44 | filePath: '$(Build.SourcesDirectory)/Build/SetVersion.ps1' 45 | workingDirectory: '$(Build.SourcesDirectory)' 46 | arguments: -path $(Build.SourcesDirectory)/Directory.Build.props -version $(assemblyVersion) 47 | displayName: Update assembly version 48 | 49 | - task: DotNetCoreCLI@2 50 | inputs: 51 | command: 'build' 52 | projects: '$(solution)' 53 | arguments: '-property:ContinuousIntegrationBuild=true --configuration $(build_configuration)' 54 | displayName: Build Solution 55 | 56 | - powershell: echo "##vso[task.setvariable variable=packageVersion]$(packageVersion)-rc.$(Build.BuildId)" 57 | displayName: Set nuget RC version for non-release branch 58 | condition: and(succeeded(), eq(variables['Build.SourceBranchName'], 'master')) 59 | 60 | - task: PowerShell@2 61 | inputs: 62 | filePath: '$(Build.SourcesDirectory)/NuGet/BuildNuspecs.ps1' 63 | workingDirectory: '$(Build.SourcesDirectory)' 64 | arguments: -path $(Build.SourcesDirectory)/NuGet/linq2db.EntityFrameworkCore.nuspec -version $(packageVersion) -branch $(Build.SourceBranchName) 65 | displayName: Generate nuspec 66 | condition: and(succeeded(), or(eq(variables['Build.SourceBranchName'], 'release'), eq(variables['Build.SourceBranchName'], 'master'))) 67 | 68 | - task: NuGetToolInstaller@1 69 | 70 | - task: CmdLine@2 71 | inputs: 72 | script: 'nuget Pack linq2db.EntityFrameworkCore.nuspec -OutputDirectory built' 73 | workingDirectory: $(Build.SourcesDirectory)/NuGet 74 | displayName: Build nuget (azure artifacts) 75 | condition: and(succeeded(), eq(variables['Build.SourceBranchName'], 'master')) 76 | 77 | - task: CmdLine@2 78 | inputs: 79 | script: 'nuget Pack linq2db.EntityFrameworkCore.nuspec -OutputDirectory built -Symbols -SymbolPackageFormat snupkg' 80 | workingDirectory: $(Build.SourcesDirectory)/NuGet 81 | displayName: Build nuget (nuget.org) 82 | condition: and(succeeded(), eq(variables['Build.SourceBranchName'], 'release')) 83 | 84 | - task: PublishBuildArtifacts@1 85 | inputs: 86 | pathToPublish: '$(Build.SourcesDirectory)/NuGet/built' 87 | artifactName: '$(artifact_nugets)' 88 | displayName: Publish nugets to artifacts 89 | condition: and(succeeded(), or(eq(variables['Build.SourceBranchName'], 'release'), eq(variables['Build.SourceBranchName'], 'master'))) 90 | 91 | - task: NuGetCommand@2 92 | inputs: 93 | command: 'push' 94 | packagesToPush: '$(Build.SourcesDirectory)/NuGet/built/linq2db.EntityFrameworkCore.*.nupkg' 95 | nuGetFeedType: 'internal' 96 | publishVstsFeed: '0dcc414b-ea54-451e-a54f-d63f05367c4b/967a4107-9788-41a4-9f6d-a2318aab1410' 97 | displayName: Publish to Azure Artifacts feed 98 | condition: and(succeeded(), eq(variables['Build.SourceBranchName'], 'master')) 99 | 100 | - task: NuGetCommand@2 101 | inputs: 102 | command: 'push' 103 | packagesToPush: '$(Build.SourcesDirectory)/NuGet/built/linq2db.EntityFrameworkCore.*.nupkg' 104 | nuGetFeedType: 'external' 105 | publishFeedCredentials: 'linq2db nuget.org feed' 106 | displayName: Publish to Nuget.org 107 | condition: and(succeeded(), eq(variables['Build.SourceBranchName'], 'release')) 108 | -------------------------------------------------------------------------------- /linq2db.EFCore.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | DB 3 | EF -------------------------------------------------------------------------------- /spellcheck.txt: -------------------------------------------------------------------------------- 1 | Impl 2 | Devart 3 | Postgre 4 | Npgsql 5 | Sqlite 6 | enums 7 | infos 8 | param 9 | Insertable 10 | instantiator 11 | params 12 | postgres 13 | nextval 14 | Cidr 15 | Inet 16 | getutcdate 17 | datediff 18 | Systemd 19 | Utils 20 | Desc 21 | Unnest 22 | xmin 23 | tsrange 24 | northwind 25 | nvarchar 26 | uniqueidentifier 27 | tinyint 28 | Deserialize 29 | varbinary 30 | mysql 31 | --------------------------------------------------------------------------------