Skip to content

Commit 21517c6

Browse files
messieurMeKirillKurdyukovrobot
authored
MVP of Entity Framework (#286)
Co-authored-by: Kirill Kurdyukov <[email protected]> Co-authored-by: robot <robot@umbrella>
1 parent b553218 commit 21517c6

File tree

83 files changed

+3674
-5
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+3674
-5
lines changed

.github/scripts/format-all-dotnet-code.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ set -eu
44

55
DIR="$1"
66
SLN_FILE="$2"
7-
PROFILE="$3"
87

98
cd "$DIR"
109

.github/workflows/lint.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ jobs:
2727
- name: Setup .NET
2828
uses: actions/setup-dotnet@v4
2929
with:
30-
dotnet-version: '8.0.x'
30+
dotnet-version: 9.0.x
3131
- name: Restore
3232
run: dotnet restore ${{ matrix.source-dir }}${{ matrix.solutionFile }}
3333
- name: Install ReSharper
3434
run: dotnet tool install -g JetBrains.ReSharper.GlobalTools
3535
- name: format all files with auto-formatter
36-
run: bash ./.github/scripts/format-all-dotnet-code.sh ${{ matrix.source-dir }} ${{ matrix.solutionFile }} "Custom Cleanup"
36+
run: bash ./.github/scripts/format-all-dotnet-code.sh ${{ matrix.source-dir }} ${{ matrix.solutionFile }}
3737
- name: Check repository diff
3838
run: bash ./.github/scripts/check-work-copy-equals-to-committed.sh "auto-format broken"
3939

@@ -48,20 +48,21 @@ jobs:
4848
- name: Checkout
4949
uses: actions/checkout@v4
5050
- name: Setup .NET
51+
id: setup-dotnet
5152
uses: actions/setup-dotnet@v4
5253
with:
53-
dotnet-version: '8.0.x'
54+
dotnet-version: 9.0.x
5455
- name: Restore
5556
run: dotnet restore ${{ matrix.solutionPath }}
5657
- name: Inspect code
5758
uses: muno92/resharper_inspectcode@v1
5859
with:
5960
solutionPath: ${{ matrix.solutionPath }}
60-
version: 2023.2.1
6161
include: |
6262
**.cs
6363
**.cshtml
6464
minimumReportSeverity: WARNING
65+
dotnetVersion: ${{ steps.setup-dotnet.outputs.dotnet-version }}
6566
ignoreIssueType: |
6667
UnusedField.Compiler,
6768
UnusedVariable.Compiler,
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
using System;
2+
3+
namespace EfCore.Ydb.Abstractions;
4+
5+
[AttributeUsage(AttributeTargets.Property)]
6+
public class YdbStringAttribute : Attribute;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using EfCore.Ydb.Extensions;
2+
using Microsoft.EntityFrameworkCore.Design;
3+
using Microsoft.Extensions.DependencyInjection;
4+
5+
namespace EfCore.Ydb.Design.Internal;
6+
7+
public class YdbDesignTimeServices : IDesignTimeServices
8+
{
9+
public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
10+
{
11+
serviceCollection.AddEntityFrameworkYdb();
12+
13+
new EntityFrameworkRelationalDesignServicesBuilder(serviceCollection)
14+
.TryAddCoreServices();
15+
}
16+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Data.Common;
2+
using Microsoft.EntityFrameworkCore.Diagnostics;
3+
4+
namespace EfCore.Ydb.Diagnostics.Internal;
5+
6+
// Temporary for debugging
7+
public class YdbCommandInterceptor : DbCommandInterceptor
8+
{
9+
public override InterceptionResult<DbDataReader> ReaderExecuting(
10+
DbCommand command,
11+
CommandEventData eventData,
12+
InterceptionResult<DbDataReader> result
13+
) => result;
14+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
using Microsoft.EntityFrameworkCore.Diagnostics;
2+
3+
namespace EfCore.Ydb.Diagnostics.Internal;
4+
5+
public class YdbLoggingDefinitions : RelationalLoggingDefinitions;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<RootNamespace>EfCore.Ydb</RootNamespace>
6+
<Nullable>enable</Nullable>
7+
<PackageId>EfCore.Ydb</PackageId>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0"/>
12+
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.0"/>
13+
<PackageReference Include="Ydb.Sdk" Version="0.15.3"/>
14+
</ItemGroup>
15+
16+
<ItemGroup>
17+
<Reference Include="Microsoft.EntityFrameworkCore.Relational">
18+
<HintPath>..\..\..\..\..\.nuget\packages\microsoft.entityframeworkcore.relational\9.0.0\lib\net8.0\Microsoft.EntityFrameworkCore.Relational.dll</HintPath>
19+
</Reference>
20+
</ItemGroup>
21+
</Project>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
using System.Data.Common;
3+
using EfCore.Ydb.Infrastructure;
4+
using EfCore.Ydb.Infrastructure.Internal;
5+
using Microsoft.EntityFrameworkCore;
6+
using Microsoft.EntityFrameworkCore.Infrastructure;
7+
8+
namespace EfCore.Ydb.Extensions;
9+
10+
public static class YdbContextOptionsBuilderExtensions
11+
{
12+
public static DbContextOptionsBuilder UseEfYdb(
13+
this DbContextOptionsBuilder optionsBuilder,
14+
string? connectionString,
15+
Action<YdbDbContextOptionsBuilder>? efYdbOptionsAction = null
16+
)
17+
{
18+
var extension = GetOrCreateExtension(optionsBuilder).WithConnectionString(connectionString);
19+
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
20+
21+
ConfigureWarnings(optionsBuilder);
22+
23+
efYdbOptionsAction?.Invoke(new YdbDbContextOptionsBuilder(optionsBuilder));
24+
return optionsBuilder;
25+
}
26+
27+
public static DbContextOptionsBuilder UseEfYdb(
28+
this DbContextOptionsBuilder optionsBuilder,
29+
DbConnection connection,
30+
Action<YdbDbContextOptionsBuilder>? efYdbOptionsAction = null
31+
)
32+
{
33+
var extension = GetOrCreateExtension(optionsBuilder).WithConnection(connection);
34+
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
35+
36+
ConfigureWarnings(optionsBuilder);
37+
38+
efYdbOptionsAction?.Invoke(new YdbDbContextOptionsBuilder(optionsBuilder));
39+
return optionsBuilder;
40+
}
41+
42+
// TODO: Right now there are no arguments for constructor, so probably it's ok
43+
private static YdbOptionsExtension GetOrCreateExtension(DbContextOptionsBuilder options)
44+
=> options.Options.FindExtension<YdbOptionsExtension>() ?? new YdbOptionsExtension();
45+
46+
private static void ConfigureWarnings(DbContextOptionsBuilder optionsBuilder)
47+
{
48+
var coreOptionsExtension = optionsBuilder.Options.FindExtension<CoreOptionsExtension>()
49+
?? new CoreOptionsExtension();
50+
51+
coreOptionsExtension = RelationalOptionsExtension.WithDefaultWarningConfiguration(coreOptionsExtension);
52+
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(coreOptionsExtension);
53+
}
54+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using EfCore.Ydb.Diagnostics.Internal;
2+
using EfCore.Ydb.Infrastructure;
3+
using EfCore.Ydb.Infrastructure.Internal;
4+
using EfCore.Ydb.Metadata.Conventions;
5+
using EfCore.Ydb.Metadata.Internal;
6+
using EfCore.Ydb.Migrations;
7+
using EfCore.Ydb.Migrations.Internal;
8+
using EfCore.Ydb.Query.Internal;
9+
using EfCore.Ydb.Storage.Internal;
10+
using EfCore.Ydb.Update.Internal;
11+
using Microsoft.EntityFrameworkCore.Diagnostics;
12+
using Microsoft.EntityFrameworkCore.Infrastructure;
13+
using Microsoft.EntityFrameworkCore.Metadata;
14+
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
15+
using Microsoft.EntityFrameworkCore.Migrations;
16+
using Microsoft.EntityFrameworkCore.Query;
17+
using Microsoft.EntityFrameworkCore.Storage;
18+
using Microsoft.EntityFrameworkCore.Update;
19+
using Microsoft.Extensions.DependencyInjection;
20+
21+
namespace EfCore.Ydb.Extensions;
22+
23+
public static class YdbServiceCollectionExtensions
24+
{
25+
public static IServiceCollection AddEntityFrameworkYdb(this IServiceCollection serviceCollection)
26+
{
27+
new EntityFrameworkYdbServicesBuilder(serviceCollection)
28+
.TryAdd<LoggingDefinitions, YdbLoggingDefinitions>()
29+
.TryAdd<IDatabaseProvider, DatabaseProvider<YdbOptionsExtension>>()
30+
.TryAdd<IRelationalTypeMappingSource, YdbTypeMappingSource>()
31+
.TryAdd<ISqlGenerationHelper, YdbSqlGenerationHelper>()
32+
.TryAdd<IRelationalAnnotationProvider, YdbAnnotationProvider>()
33+
.TryAdd<IModelValidator, YdbModelValidator>()
34+
.TryAdd<IProviderConventionSetBuilder, YdbConventionSetBuilder>()
35+
.TryAdd<IUpdateSqlGenerator, YdbUpdateSqlGenerator>()
36+
.TryAdd<IModificationCommandFactory, YdbModificationCommandFactory>()
37+
.TryAdd<IRelationalTransactionFactory, YdbRelationalTransactionFactory>()
38+
.TryAdd<IModificationCommandBatchFactory, YdbModificationCommandBatchFactory>()
39+
.TryAdd<IRelationalConnection>(p => p.GetRequiredService<IYdbRelationalConnection>())
40+
.TryAdd<IMigrationsSqlGenerator, YdbMigrationsSqlGenerator>()
41+
.TryAdd<IRelationalDatabaseCreator, YdbDatabaseCreator>()
42+
.TryAdd<IHistoryRepository, YdbHistoryRepository>()
43+
.TryAdd<IQueryableMethodTranslatingExpressionVisitorFactory,
44+
YdbQueryableMethodTranslatingExpressionVisitorFactory>()
45+
.TryAdd<IMethodCallTranslatorProvider, YdbMethodCallTranslatorProvider>()
46+
.TryAdd<IAggregateMethodCallTranslatorProvider, YdbAggregateMethodCallTranslatorProvider>()
47+
.TryAdd<IMemberTranslatorProvider, YdbMemberTranslatorProvider>()
48+
.TryAdd<IQuerySqlGeneratorFactory, YdbQuerySqlGeneratorFactory>()
49+
.TryAdd<IRelationalSqlTranslatingExpressionVisitorFactory, YdbSqlTranslatingExpressionVisitorFactory>()
50+
.TryAdd<IQueryTranslationPostprocessorFactory, YdbQueryTranslationPostprocessorFactory>()
51+
.TryAdd<IRelationalParameterBasedSqlProcessorFactory, YdbParameterBasedSqlProcessorFactory>()
52+
.TryAdd<ISqlExpressionFactory, YdbSqlExpressionFactory>()
53+
.TryAdd<IQueryCompilationContextFactory, YdbQueryCompilationContextFactory>()
54+
.TryAddProviderSpecificServices(b => b
55+
.TryAddScoped<IYdbRelationalConnection, YdbRelationalConnection>()
56+
.TryAddScoped<IDbCommandInterceptor, YdbCommandInterceptor>())
57+
.TryAddCoreServices();
58+
59+
return serviceCollection;
60+
}
61+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Microsoft.EntityFrameworkCore.Infrastructure;
4+
using Microsoft.Extensions.DependencyInjection;
5+
6+
namespace EfCore.Ydb.Infrastructure;
7+
8+
public class EntityFrameworkYdbServicesBuilder(IServiceCollection serviceCollection)
9+
: EntityFrameworkRelationalServicesBuilder(serviceCollection)
10+
{
11+
// ReSharper disable once CollectionNeverUpdated.Local
12+
#pragma warning disable CA1859
13+
private static readonly IDictionary<Type, ServiceCharacteristics> YdbServices
14+
#pragma warning restore CA1859
15+
= new Dictionary<Type, ServiceCharacteristics>
16+
{
17+
// TODO: Add items if required
18+
};
19+
20+
protected override ServiceCharacteristics GetServiceCharacteristics(Type serviceType)
21+
{
22+
var contains = YdbServices.TryGetValue(serviceType, out var characteristics);
23+
return contains
24+
? characteristics
25+
: base.GetServiceCharacteristics(serviceType);
26+
}
27+
}

0 commit comments

Comments
 (0)