├── .editorconfig
├── .gitignore
├── Build
├── SetVersion.ps1
├── linq2db.Default.props
├── linq2db.Tests.props
└── linq2db.snk
├── 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
│ ├── LinqToDBExtensionsAdapter.cs
│ ├── LinqToDBForEFExtensions.Async.EF.cs
│ ├── LinqToDBForEFExtensions.Async.cs
│ ├── LinqToDBForEFTools.ContextExtensions.cs
│ ├── LinqToDBForEFTools.Extensions.cs
│ ├── LinqToDBForEFTools.Mapping.cs
│ ├── LinqToDBForEFTools.cs
│ ├── LinqToDBForEFToolsDataConnection.cs
│ ├── LinqToDBForEFToolsDataContext.cs
│ ├── LinqToDBForEFToolsException.cs
│ ├── LinqToDBForEFToolsImplDefault.cs
│ ├── LinqToDBProviderInfo.cs
│ ├── Properties
│ └── JetBrains.Annotations.cs
│ └── linq2db.EntityFrameworkCore.csproj
├── Tests
├── LinqToDB.EntityFrameworkCore.BaseTests
│ ├── LinqToDB.EntityFrameworkCore.BaseTests.csproj
│ ├── Logging
│ │ ├── LogMessageEntry.cs
│ │ ├── NullExternalScopeProvider.cs
│ │ ├── NullScope.cs
│ │ ├── TestLogger.cs
│ │ ├── TestLoggerExtensions.cs
│ │ └── TestLoggerProvider.cs
│ ├── Models
│ │ └── 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.PomeloMySql.Tests
│ ├── LinqToDB.EntityFrameworkCore.PomeloMySql.Tests.csproj
│ ├── Models
│ │ ├── 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
│ ├── LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.csproj
│ ├── Models
│ │ └── NpgSqlEntities
│ │ │ ├── Event.cs
│ │ │ ├── EventView.cs
│ │ │ └── NpgSqlEnititesContext.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
│ ├── LinqToDB.EntityFrameworkCore.SQLite.Tests.csproj
│ ├── Models
│ │ ├── 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
│ ├── IssueTests.cs
│ ├── JsonConverTests.cs
│ ├── LinqToDB.EntityFrameworkCore.SqlServer.Tests.csproj
│ ├── Models
│ ├── IssueModel
│ │ ├── 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
│ ├── QueryableExtensions.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
/.gitignore:
--------------------------------------------------------------------------------
1 | #ignore thumbnails created by windows
2 | Thumbs.db
3 | #Ignore files build by Visual Studio
4 | *.obj
5 | *.pdb
6 | *.user
7 | *.aps
8 | *.pch
9 | *.vspscc
10 | *_i.c
11 | *_p.c
12 | *.ncb
13 | *.suo
14 | *.tlb
15 | *.tlh
16 | *.bak
17 | *.cache
18 | *.ilk
19 | *.log
20 | *.cs.ide
21 | [Bb]in
22 | [Dd]ebug*/
23 | *.lib
24 | *.sbr
25 | obj/
26 | [Rr]elease*/
27 | _ReSharper*/
28 | [Tt]est[Rr]esult*
29 | linq2db.sln.docstates
30 | Tests/**/UserDataProviders*.*
31 | NuGet/*.nupkg
32 | !*.dll
33 | !*.exe
34 | !*.pdb
35 | linq2db.sln.ide/graph
36 | linq2db.sln.ide/
37 | !Redist/**
38 | /packages
39 | /.vs/*
40 | *.lock.json
41 | /api
42 | /linq2db.github.io
43 | #cake
44 | /tools
45 | /.tools
46 | /.idea/
47 |
--------------------------------------------------------------------------------
/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.Default.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | 5.1.6
4 |
5 | Svyatoslav Danyliv, Igor Tkachev, Dmitry Lukashenko, Ilya Chudin
6 | Linq to DB
7 | linq2db.net
8 | 2002-2020 linq2db.net
9 | https://github.com/linq2db/linq2db.EntityFrameworkCore
10 | git
11 |
12 | 9.0
13 | enable
14 | 4
15 | prompt
16 | preview
17 |
18 | false
19 | false
20 | True
21 | ..\..\Build\linq2db.snk
22 | False
23 |
24 | true
25 | true
26 | true
27 | true
28 | true
29 | true
30 | false
31 |
32 |
33 |
34 | preview
35 |
36 | false
37 | false
38 |
39 |
40 | true
41 | true
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Build/linq2db.Tests.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | netcoreapp3.1
7 |
8 |
9 |
10 |
11 |
12 | all
13 | runtime; build; native; contentfiles; analyzers; buildtransitive
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Build/linq2db.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ualehosaini/linq2db.EntityFrameworkCore/81b82c1acbe56fa33d00a4818ac5592d6e75f187/Build/linq2db.snk
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/ualehosaini/linq2db.EntityFrameworkCore/81b82c1acbe56fa33d00a4818ac5592d6e75f187/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 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 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 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/ILinqToDBForEFTools.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Linq.Expressions;
3 |
4 | using Microsoft.EntityFrameworkCore;
5 | using Microsoft.EntityFrameworkCore.Diagnostics;
6 | using Microsoft.EntityFrameworkCore.Infrastructure;
7 | using Microsoft.EntityFrameworkCore.Metadata;
8 | using Microsoft.EntityFrameworkCore.Query;
9 | using Microsoft.EntityFrameworkCore.Storage;
10 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
11 | using Microsoft.Extensions.Logging;
12 |
13 | namespace LinqToDB.EntityFrameworkCore
14 | {
15 | using DataProvider;
16 | using Mapping;
17 | using Metadata;
18 | using Data;
19 |
20 | ///
21 | /// Interface for EF.Core - LINQ To DB integration bridge.
22 | ///
23 | public interface ILinqToDBForEFTools
24 | {
25 | ///
26 | /// Clears internal caches
27 | ///
28 | void ClearCaches();
29 |
30 | ///
31 | /// Returns LINQ To DB provider, based on provider data from EF.Core.
32 | ///
33 | /// Provider information, extracted from EF.Core.
34 | /// Database connection information.
35 | /// LINQ TO DB provider instance.
36 | IDataProvider? GetDataProvider(EFProviderInfo providerInfo, EFConnectionInfo connectionInfo);
37 |
38 | ///
39 | /// Creates metadata provider for specified EF.Core data model.
40 | ///
41 | /// EF.Core data model.
42 | ///
43 | ///
44 | ///
45 | /// LINQ To DB metadata provider for specified EF.Core model. Can return null.
46 | IMetadataReader? CreateMetadataReader(
47 | IModel? model,
48 | RelationalSqlTranslatingExpressionVisitorDependencies? dependencies,
49 | IRelationalTypeMappingSource? mappingSource,
50 | IDiagnosticsLogger? logger);
51 |
52 | ///
53 | /// Creates mapping schema using provided EF.Core data model and metadata provider.
54 | ///
55 | /// EF.Core data model.
56 | /// Additional optional LINQ To DB database metadata provider.
57 | /// EF Core registry for type conversion.
58 | /// Mapping schema for provided EF.Core model.
59 | MappingSchema CreateMappingSchema(IModel model, IMetadataReader metadataReader, IValueConverterSelector convertorSelector);
60 |
61 | ///
62 | /// Returns mapping schema using provided EF.Core data model and metadata provider.
63 | ///
64 | /// EF.Core data model.
65 | /// Additional optional LINQ To DB database metadata provider.
66 | /// EF Core registry for type conversion.
67 | /// Mapping schema for provided EF.Core model.
68 | MappingSchema GetMappingSchema(IModel model, IMetadataReader? metadataReader, IValueConverterSelector? convertorSelector);
69 |
70 | ///
71 | /// Returns EF.Core for specific instance.
72 | ///
73 | /// EF.Core instance.
74 | /// instance.
75 | IDbContextOptions? GetContextOptions(DbContext? context);
76 |
77 | ///
78 | /// Transforms EF.Core expression tree to LINQ To DB expression.
79 | ///
80 | /// EF.Core expression tree.
81 | /// LINQ To DB instance.
82 | /// Optional DbContext instance.
83 | /// EF.Core data model instance.
84 | /// Transformed expression.
85 | Expression TransformExpression(Expression expression, IDataContext dc, DbContext? ctx, IModel? model);
86 |
87 | ///
88 | /// Extracts instance from object.
89 | ///
90 | /// EF.Core query.
91 | /// Current instance.
92 | DbContext? GetCurrentContext(IQueryable query);
93 |
94 | ///
95 | /// Extracts EF.Core connection information object from .
96 | ///
97 | /// instance.
98 | /// EF.Core connection data.
99 | EFConnectionInfo ExtractConnectionInfo(IDbContextOptions? options);
100 |
101 | ///
102 | /// Extracts EF.Core data model instance from .
103 | ///
104 | /// instance.
105 | /// EF.Core data model instance.
106 | IModel? ExtractModel(IDbContextOptions? options);
107 |
108 | ///
109 | /// Creates logger used for logging Linq To DB connection calls.
110 | ///
111 | /// instance.
112 | /// Logger instance.
113 | ILogger? CreateLogger(IDbContextOptions? options);
114 |
115 | ///
116 | /// Logs DataConnection information.
117 | ///
118 | ///
119 | ///
120 | void LogConnectionTrace(TraceInfo info, ILogger logger);
121 |
122 | ///
123 | /// Enables attaching entities to change tracker.
124 | /// Entities will be attached only if AsNoTracking() is not used in query and DbContext is configured to track entities.
125 | ///
126 | bool EnableChangeTracker { get; set; }
127 |
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/Source/LinqToDB.EntityFrameworkCore/Internal/EFCoreExpressionAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Linq.Expressions;
5 | using LinqToDB.Mapping;
6 | using LinqToDB.SqlQuery;
7 |
8 | namespace LinqToDB.EntityFrameworkCore.Internal
9 | {
10 | ///
11 | /// Maps linq2db exression.
12 | ///
13 | public class EFCoreExpressionAttribute : Sql.ExpressionAttribute
14 | {
15 | ///
16 | /// Creates instance of expression mapper.
17 | ///
18 | /// Mapped expression.
19 | public EFCoreExpressionAttribute(string expression) : base(expression)
20 | {
21 | }
22 |
23 | ///
24 | public override ISqlExpression GetExpression(
25 | IDataContext dataContext,
26 | SelectQuery query,
27 | Expression expression,
28 | Func converter)
29 | {
30 | var knownExpressions = new List();
31 | if (expression.NodeType == ExpressionType.Call)
32 | {
33 | var mc = (MethodCallExpression) expression;
34 | if (!mc.Method.IsStatic)
35 | knownExpressions.Add(mc.Object);
36 | knownExpressions.AddRange(mc.Arguments);
37 | }
38 | else
39 | {
40 | var me = (MemberExpression) expression;
41 | knownExpressions.Add(me.Expression);
42 | }
43 |
44 | var pams = new List(knownExpressions.Select(_ => (ISqlExpression?) null));
45 |
46 | _ = Sql.ExtensionAttribute.ResolveExpressionValues(Expression!,
47 | (v, d) =>
48 | {
49 | var idx = int.Parse(v);
50 |
51 | if (pams[idx] == null)
52 | pams[idx] = converter(knownExpressions[idx], null);
53 |
54 | return v;
55 | });
56 |
57 | var parameters = pams.Select(p => p ?? new SqlExpression("!!!")).ToArray();
58 | return new SqlExpression(expression.Type, Expression!, Precedence, parameters);
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Source/LinqToDB.EntityFrameworkCore/Internal/LinqToDBForEFQueryProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Linq.Expressions;
6 | using System.Reflection;
7 | using System.Threading;
8 | using System.Threading.Tasks;
9 |
10 | using Microsoft.EntityFrameworkCore.Query;
11 | using LinqToDB.Expressions;
12 |
13 | namespace LinqToDB.EntityFrameworkCore.Internal
14 | {
15 | using Async;
16 | using Linq;
17 |
18 | ///
19 | /// Adapter for
20 | /// This is internal API and is not intended for use by Linq To DB applications.
21 | /// It may change or be removed without further notice.
22 | ///
23 | /// Type of query element.
24 | public class LinqToDBForEFQueryProvider : IAsyncQueryProvider, IQueryProviderAsync, IQueryable, IAsyncEnumerable
25 | {
26 | ///
27 | /// Creates instance of adapter.
28 | ///
29 | /// Data context instance.
30 | /// Query expression.
31 | public LinqToDBForEFQueryProvider(IDataContext dataContext, Expression expression)
32 | {
33 | if (expression == null) throw new ArgumentNullException(nameof(expression));
34 | var dataContext1 = dataContext ?? throw new ArgumentNullException(nameof(dataContext));
35 | QueryProvider = (IQueryProviderAsync) Internals.CreateExpressionQueryInstance(dataContext1, expression);
36 | QueryProviderAsQueryable = (IQueryable) QueryProvider;
37 | }
38 |
39 | IQueryProviderAsync QueryProvider { get; }
40 | IQueryable QueryProviderAsQueryable { get; }
41 |
42 | ///
43 | /// Creates instance from query expression.
44 | ///
45 | /// Query expression.
46 | /// instance.
47 | public IQueryable CreateQuery(Expression expression)
48 | {
49 | return QueryProvider.CreateQuery(expression);
50 | }
51 |
52 | ///
53 | /// Creates instance from query expression.
54 | ///
55 | /// Query element type.
56 | /// Query expression.
57 | /// instance.
58 | public IQueryable CreateQuery(Expression expression)
59 | {
60 | return QueryProvider.CreateQuery(expression);
61 | }
62 |
63 | ///
64 | /// Executes query expression.
65 | ///
66 | /// Query expression.
67 | /// Query result.
68 | public object Execute(Expression expression)
69 | {
70 | return QueryProvider.Execute(expression);
71 | }
72 |
73 | ///
74 | /// Executes query expression and returns typed result.
75 | ///
76 | /// Type of result.
77 | /// Query expression.
78 | /// Query result.
79 | public TResult Execute(Expression expression)
80 | {
81 | return QueryProvider.Execute(expression);
82 | }
83 |
84 | private static readonly MethodInfo _executeAsyncMethodInfo =
85 | MemberHelper.MethodOf((IQueryProviderAsync p) => p.ExecuteAsync(null!, default)).GetGenericMethodDefinition();
86 |
87 | ///
88 | /// Executes query expression and returns result as value.
89 | ///
90 | /// Type of result element.
91 | /// Query expression.
92 | /// Cancellation token.
93 | /// Query result as .
94 | public Task> ExecuteAsyncEnumerable(Expression expression, CancellationToken token)
95 | {
96 | return QueryProvider.ExecuteAsyncEnumerable(expression, token);
97 | }
98 |
99 | ///
100 | /// Executes query expression and returns typed result.
101 | ///
102 | /// Type of result.
103 | /// Query expression.
104 | /// Cancellation token.
105 | /// Query result.
106 | TResult IAsyncQueryProvider.ExecuteAsync(Expression expression, CancellationToken cancellationToken)
107 | {
108 | var item = typeof(TResult).GetGenericArguments()[0];
109 | var method = _executeAsyncMethodInfo.MakeGenericMethod(item);
110 | return (TResult) method.Invoke(QueryProvider, new object[] { expression, cancellationToken });
111 | }
112 |
113 | ///
114 | /// Executes query expression and returns typed result.
115 | ///
116 | /// Type of result.
117 | /// Query expression.
118 | /// Cancellation token.
119 | /// Query result.
120 | public Task ExecuteAsync(Expression expression, CancellationToken cancellationToken)
121 | {
122 | return QueryProvider.ExecuteAsync(expression, cancellationToken);
123 | }
124 |
125 | IEnumerator IEnumerable.GetEnumerator()
126 | {
127 | return QueryProviderAsQueryable.GetEnumerator();
128 | }
129 |
130 | IEnumerator IEnumerable.GetEnumerator()
131 | {
132 | return QueryProviderAsQueryable.GetEnumerator();
133 | }
134 |
135 | #region IQueryable
136 |
137 | ///
138 | /// Type of query element.
139 | ///
140 | public Type ElementType => typeof(T);
141 |
142 | ///
143 | /// Query expression.
144 | ///
145 | public Expression Expression => QueryProviderAsQueryable.Expression;
146 |
147 | ///
148 | /// Query provider.
149 | ///
150 | public IQueryProvider Provider => this;
151 |
152 | #endregion
153 |
154 | ///
155 | /// Gets for current query.
156 | ///
157 | /// Cancellation token.
158 | /// Query result as .
159 | public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken)
160 | {
161 | return QueryProvider.ExecuteAsyncEnumerable(Expression, cancellationToken).Result.GetAsyncEnumerator(cancellationToken);
162 | }
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/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 | if (context == null)
18 | throw new LinqToDBForEFToolsException($"Can not load current context from {nameof(dbSet)}");
19 |
20 | var dc = CreateLinqToDbContext(context);
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 |
16 | static void InitializeMapping()
17 | {
18 | Linq.Expressions.MapMember(
19 | (DbFunctions f, string m, string p) => f.Like(m, p), (f, m, p) => Sql.Like(m, p));
20 |
21 | // InitializeSqlServerMapping();
22 | }
23 |
24 |
25 | #region Sql Server
26 |
27 | static Sql.DateParts? GetDatePart(string name)
28 | {
29 | switch (name)
30 | {
31 | case "Year" : return Sql.DateParts.Year;
32 | case "Day" : return Sql.DateParts.Day;
33 | case "Month" : return Sql.DateParts.Month;
34 | case "Hour" : return Sql.DateParts.Hour;
35 | case "Minute" : return Sql.DateParts.Minute;
36 | case "Second" : return Sql.DateParts.Second;
37 | case "Millisecond": return Sql.DateParts.Millisecond;
38 | }
39 |
40 | return null;
41 | }
42 |
43 | ///
44 | /// Initilaizes SQL Server's DbFunctions dynamically to avoid dependency
45 | ///
46 | static void InitializeSqlServerMapping()
47 | {
48 | var type = Type.GetType("Microsoft.EntityFrameworkCore.SqlServerDbFunctionsExtensions, Microsoft.EntityFrameworkCore.SqlServer", false);
49 |
50 | if (type == null)
51 | return;
52 |
53 | var sqlServerMethods = type.GetMethods(BindingFlags.Public | BindingFlags.Static)
54 | .Where(m => m.GetParameters().Length > 0)
55 | .ToArray();
56 |
57 | var dbFunctionsParameter = Expression.Parameter(typeof(DateTime), "dbFunctions");
58 |
59 | var dateDiffStr = "DateDiff";
60 | var dateDiffMethods = sqlServerMethods.Where(m => m.Name.StartsWith(dateDiffStr)).ToArray();
61 |
62 | var dateDiffMethod = MemberHelper.MethodOf(() => Sql.DateDiff(Sql.DateParts.Day, null, null));
63 |
64 | foreach (var method in dateDiffMethods)
65 | {
66 | var datePart = GetDatePart(method.Name.Substring(dateDiffStr.Length));
67 | if (datePart == null)
68 | continue;
69 |
70 | var parameters = method.GetParameters();
71 | if (parameters.Length < 3)
72 | continue;
73 |
74 | var boundaryType = parameters[1].ParameterType;
75 | if (boundaryType.ToUnderlying() != typeof(DateTime))
76 | continue;
77 |
78 | var startParameter = Expression.Parameter(boundaryType, "start");
79 | var endParameter = Expression.Parameter(boundaryType, "end");
80 |
81 | var startExpr = startParameter.Type != typeof(DateTime?)
82 | ? (Expression) Expression.Convert(startParameter, typeof(DateTime?))
83 | : startParameter;
84 |
85 | var endExpr = endParameter.Type != typeof(DateTime?)
86 | ? (Expression) Expression.Convert(endParameter, typeof(DateTime?))
87 | : endParameter;
88 |
89 |
90 | var body = Expression.Call(dateDiffMethod, Expression.Constant(datePart.Value), startExpr, endExpr);
91 | var lambda = Expression.Lambda(body, dbFunctionsParameter, startParameter, endParameter);
92 |
93 | Linq.Expressions.MapMember(method, lambda);
94 | }
95 | }
96 |
97 | #endregion
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFToolsDataConnection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Data;
3 | using System.Linq;
4 | using System.Linq.Expressions;
5 |
6 | using Microsoft.EntityFrameworkCore.Metadata;
7 |
8 | using Microsoft.EntityFrameworkCore;
9 | using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
10 | using Microsoft.EntityFrameworkCore.Infrastructure;
11 | using Microsoft.EntityFrameworkCore.Storage;
12 |
13 | namespace LinqToDB.EntityFrameworkCore
14 | {
15 | using System.Diagnostics.CodeAnalysis;
16 | using Data;
17 | using DataProvider;
18 | using Linq;
19 |
20 | ///
21 | /// linq2db EF.Core data connection.
22 | ///
23 | public class LinqToDBForEFToolsDataConnection : DataConnection, IExpressionPreprocessor
24 | {
25 | readonly IModel? _model;
26 | readonly Func? _transformFunc;
27 |
28 | private IEntityType? _lastEntityType;
29 | private Type? _lastType;
30 | private IStateManager? _stateManager;
31 |
32 | ///
33 | /// Change tracker enable flag.
34 | ///
35 | public bool Tracking { get; set; }
36 |
37 | ///
38 | /// EF.Core database context.
39 | ///
40 | public DbContext? Context { get; }
41 |
42 | ///
43 | /// Creates new instance of data connection.
44 | ///
45 | /// EF.Core database context.
46 | /// linq2db database provider.
47 | /// Connection string.
48 | /// EF.Core data model.
49 | /// Expression converter.
50 | public LinqToDBForEFToolsDataConnection(
51 | DbContext? context,
52 | [NotNull] IDataProvider dataProvider,
53 | [NotNull] string connectionString,
54 | IModel? model,
55 | Func? transformFunc) : base(dataProvider, connectionString)
56 | {
57 | Context = context;
58 | _model = model;
59 | _transformFunc = transformFunc;
60 | CopyDatabaseProperties();
61 | if (LinqToDBForEFTools.EnableChangeTracker)
62 | OnEntityCreated += OnEntityCreatedHandler;
63 | }
64 |
65 | ///
66 | /// Creates new instance of data connection.
67 | ///
68 | /// EF.Core database context.
69 | /// linq2db database provider.
70 | /// Database transaction.
71 | /// EF.Core data model.
72 | /// Expression converter.
73 | public LinqToDBForEFToolsDataConnection(
74 | DbContext? context,
75 | [NotNull] IDataProvider dataProvider,
76 | [NotNull] IDbTransaction transaction,
77 | IModel? model,
78 | Func? transformFunc
79 | ) : base(dataProvider, transaction)
80 | {
81 | Context = context;
82 | _model = model;
83 | _transformFunc = transformFunc;
84 | CopyDatabaseProperties();
85 | if (LinqToDBForEFTools.EnableChangeTracker)
86 | OnEntityCreated += OnEntityCreatedHandler;
87 | }
88 |
89 | ///
90 | /// Creates new instance of data connection.
91 | ///
92 | /// EF.Core database context.
93 | /// linq2db database provider.
94 | /// Database connection instance.
95 | /// EF.Core data model.
96 | /// Expression converter.
97 | public LinqToDBForEFToolsDataConnection(
98 | DbContext? context,
99 | [NotNull] IDataProvider dataProvider,
100 | [NotNull] IDbConnection connection,
101 | IModel? model,
102 | Func? transformFunc) : base(dataProvider, connection)
103 | {
104 | Context = context;
105 | _model = model;
106 | _transformFunc = transformFunc;
107 | CopyDatabaseProperties();
108 | if (LinqToDBForEFTools.EnableChangeTracker)
109 | OnEntityCreated += OnEntityCreatedHandler;
110 | }
111 |
112 | ///
113 | /// Converts expression using convert function, passed to context.
114 | ///
115 | /// Expression to convert.
116 | /// Converted expression.
117 | public Expression ProcessExpression(Expression expression)
118 | {
119 | if (_transformFunc == null)
120 | return expression;
121 | return _transformFunc(expression, this, Context, _model);
122 | }
123 |
124 | private void OnEntityCreatedHandler(EntityCreatedEventArgs args)
125 | {
126 | if (!LinqToDBForEFTools.EnableChangeTracker
127 | || !Tracking
128 | || Context!.ChangeTracker.QueryTrackingBehavior == QueryTrackingBehavior.NoTracking)
129 | return;
130 |
131 | var type = args.Entity.GetType();
132 | if (_lastType != type)
133 | {
134 | _lastType = type;
135 | _lastEntityType = Context.Model.FindEntityType(type);
136 | }
137 |
138 | if (_lastEntityType == null)
139 | return;
140 |
141 | if (_stateManager == null)
142 | _stateManager = Context.GetService();
143 |
144 |
145 | // It is a real pain to register entity in change tracker
146 | //
147 | InternalEntityEntry? entry = null;
148 |
149 | foreach (var key in _lastEntityType.GetKeys())
150 | {
151 | //TODO: Find faster way
152 | var keyArray = key.Properties.Where(p => p.PropertyInfo != null || p.FieldInfo != null).Select(p =>
153 | p.PropertyInfo != null
154 | ? p.PropertyInfo.GetValue(args.Entity)
155 | : p.FieldInfo.GetValue(args.Entity)).ToArray();
156 |
157 | if (keyArray.Length == key.Properties.Count)
158 | {
159 | entry = _stateManager.TryGetEntry(key, keyArray);
160 |
161 | if (entry != null)
162 | break;
163 | }
164 | }
165 |
166 | if (entry == null)
167 | {
168 | entry = _stateManager.StartTrackingFromQuery(_lastEntityType, args.Entity, ValueBuffer.Empty);
169 | }
170 |
171 | args.Entity = entry.Entity;
172 | }
173 |
174 | private void CopyDatabaseProperties()
175 | {
176 | var commandTimeout = Context?.Database.GetCommandTimeout();
177 | if (commandTimeout != null)
178 | CommandTimeout = commandTimeout.Value;
179 | }
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/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 | /// linq2db 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 | }
56 |
--------------------------------------------------------------------------------
/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 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 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 = Version ?? providerInfo.Version;
28 | ProviderName = ProviderName ?? providerInfo.ProviderName;
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Source/LinqToDB.EntityFrameworkCore/Properties/JetBrains.Annotations.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | #pragma warning disable 1591
4 | // ReSharper disable UnusedMember.Global
5 | // ReSharper disable MemberCanBePrivate.Global
6 | // ReSharper disable UnusedAutoPropertyAccessor.Global
7 | // ReSharper disable IntroduceOptionalParameters.Global
8 | // ReSharper disable MemberCanBeProtected.Global
9 | // ReSharper disable InconsistentNaming
10 |
11 | namespace JetBrains.Annotations
12 | {
13 | ///
14 | /// Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library),
15 | /// so this symbol will not be marked as unused (as well as by other usage inspections).
16 | ///
17 | [AttributeUsage(AttributeTargets.All)]
18 | internal sealed class UsedImplicitlyAttribute : Attribute
19 | {
20 | public UsedImplicitlyAttribute()
21 | : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default)
22 | {
23 | }
24 |
25 | public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags)
26 | : this(useKindFlags, ImplicitUseTargetFlags.Default)
27 | {
28 | }
29 |
30 | public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags)
31 | : this(ImplicitUseKindFlags.Default, targetFlags)
32 | {
33 | }
34 |
35 | public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
36 | {
37 | UseKindFlags = useKindFlags;
38 | TargetFlags = targetFlags;
39 | }
40 |
41 | public ImplicitUseKindFlags UseKindFlags { get; private set; }
42 | public ImplicitUseTargetFlags TargetFlags { get; private set; }
43 | }
44 |
45 | ///
46 | /// Should be used on attributes and causes ReSharper to not mark symbols marked with such attributes
47 | /// as unused (as well as by other usage inspections)
48 | ///
49 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.GenericParameter)]
50 | internal sealed class MeansImplicitUseAttribute : Attribute
51 | {
52 | public MeansImplicitUseAttribute()
53 | : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default)
54 | {
55 | }
56 |
57 | public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags)
58 | : this(useKindFlags, ImplicitUseTargetFlags.Default)
59 | {
60 | }
61 |
62 | public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags)
63 | : this(ImplicitUseKindFlags.Default, targetFlags)
64 | {
65 | }
66 |
67 | public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
68 | {
69 | UseKindFlags = useKindFlags;
70 | TargetFlags = targetFlags;
71 | }
72 |
73 | [UsedImplicitly] public ImplicitUseKindFlags UseKindFlags { get; private set; }
74 | [UsedImplicitly] public ImplicitUseTargetFlags TargetFlags { get; private set; }
75 | }
76 |
77 | [Flags]
78 | internal enum ImplicitUseKindFlags
79 | {
80 | Default = Access | Assign | InstantiatedWithFixedConstructorSignature,
81 | /// Only entity marked with attribute considered used.
82 | Access = 1,
83 | /// Indicates implicit assignment to a member.
84 | Assign = 2,
85 | ///
86 | /// Indicates implicit instantiation of a type with fixed constructor signature.
87 | /// That means any unused constructor parameters won't be reported as such.
88 | ///
89 | InstantiatedWithFixedConstructorSignature = 4,
90 | /// Indicates implicit instantiation of a type.
91 | InstantiatedNoFixedConstructorSignature = 8,
92 | }
93 |
94 | ///
95 | /// Specify what is considered used implicitly when marked
96 | /// with or .
97 | ///
98 | [Flags]
99 | internal enum ImplicitUseTargetFlags
100 | {
101 | Default = Itself,
102 | Itself = 1,
103 | /// Members of entity marked with attribute are considered used.
104 | Members = 2,
105 | /// Entity marked with attribute and all its members considered used.
106 | WithMembers = Itself | Members
107 | }
108 |
109 | ///
110 | /// This attribute is intended to mark publicly available API
111 | /// which should not be removed and so is treated as used.
112 | ///
113 | [MeansImplicitUse(ImplicitUseTargetFlags.WithMembers)]
114 | [AttributeUsage(AttributeTargets.All)]
115 | internal sealed class PublicAPIAttribute : Attribute
116 | {
117 | public PublicAPIAttribute()
118 | {
119 | }
120 |
121 | public PublicAPIAttribute(string comment)
122 | {
123 | Comment = comment;
124 | }
125 |
126 | public string? Comment { get; private set; }
127 | }
128 |
129 | ///
130 | /// Indicates that a method does not make any observable state changes.
131 | /// The same as System.Diagnostics.Contracts.PureAttribute.
132 | ///
133 | ///
134 | /// [Pure] int Multiply(int x, int y) => x * y;
135 | ///
136 | /// void M() {
137 | /// Multiply(123, 42); // Waring: Return value of pure method is not used
138 | /// }
139 | ///
140 | [AttributeUsage(AttributeTargets.Method)]
141 | internal sealed class PureAttribute : Attribute
142 | {
143 | }
144 |
145 | ///
146 | /// Indicates that method is pure LINQ method, with postponed enumeration (like Enumerable.Select,
147 | /// .Where). This annotation allows inference of [InstantHandle] annotation for parameters
148 | /// of delegate type by analyzing LINQ method chains.
149 | ///
150 | [AttributeUsage(AttributeTargets.Method)]
151 | internal sealed class LinqTunnelAttribute : Attribute
152 | {
153 | }
154 |
155 |
156 | }
157 |
--------------------------------------------------------------------------------
/Source/LinqToDB.EntityFrameworkCore/linq2db.EntityFrameworkCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Allows to execute Linq to DB (linq2db) queries in Entity Framework Core DbContext.
7 | Linq to DB (linq2db) extensions for Entity Framework Core
8 | $(Title)
9 |
10 | netstandard2.1
11 | LinqToDB.EntityFrameworkCore
12 | bin\$(Configuration)\$(TargetFramework)\linq2db.EntityFrameworkCore.xml
13 |
14 |
15 | EF1001
16 | latest
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/Tests/LinqToDB.EntityFrameworkCore.BaseTests/Logging/LogMessageEntry.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
4 | {
5 | internal readonly struct LogMessageEntry
6 | {
7 | public LogMessageEntry(string message, string? timeStamp = null, string? levelString = null, ConsoleColor? levelBackground = null, ConsoleColor? levelForeground = null, ConsoleColor? messageColor = null, bool logAsError = false)
8 | {
9 | TimeStamp = timeStamp;
10 | LevelString = levelString;
11 | LevelBackground = levelBackground;
12 | LevelForeground = levelForeground;
13 | MessageColor = messageColor;
14 | Message = message;
15 | LogAsError = logAsError;
16 | }
17 |
18 | public readonly string? TimeStamp;
19 | public readonly string? LevelString;
20 | public readonly ConsoleColor? LevelBackground;
21 | public readonly ConsoleColor? LevelForeground;
22 | public readonly ConsoleColor? MessageColor;
23 | public readonly string Message;
24 | public readonly bool LogAsError;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/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 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