Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,17 +126,17 @@ jobs:
- name: Run EntityFrameworkCore.Ydb.QuickStart
run: |
cd ./examples/EntityFrameworkCore.Ydb.QuickStart
dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet tool install --global dotnet-ef --version 9.0.10
dotnet add package Microsoft.EntityFrameworkCore.Design --version 9.0.10
dotnet ef migrations add InitialCreate
dotnet ef database update
dotnet run

- name: Run EntityFrameworkCore.Ydb.Samples/Database.Operations.Tutorial
run: |
cd ./examples/EntityFrameworkCore.Ydb.Samples/Database.Operations.Tutorial
dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet tool install --global dotnet-ef --version 9.0.10
dotnet add package Microsoft.EntityFrameworkCore.Design --version 9.0.10
dotnet ef migrations add InitialCreate
dotnet ef database update
dotnet run
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.5">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.10">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
4 changes: 2 additions & 2 deletions examples/EntityFrameworkCore.Ydb.QuickStart/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ shows how to get started with EF, define a model, populate it with data and then

2. Create the database:
```bash
dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet tool install --global dotnet-ef --version 9.0.10
dotnet add package Microsoft.EntityFrameworkCore.Design --version 9.0.10
dotnet ef migrations add InitialCreate
dotnet ef database update
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.5">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.10">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ Based on the [tutorial](https://www.csharptutorial.net/entity-framework-core-tut

2. Install the EF Core CLI tool and dependencies (if needed):
```bash
dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet tool install --global dotnet-ef --version 9.0.10
dotnet add package Microsoft.EntityFrameworkCore.Design --version 9.0.10
```

3. Create the database and apply migrations:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.5">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.10">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ Based on the [tutorial](https://www.csharptutorial.net/entity-framework-core-tut

2. Install the EF Core CLI tool and dependencies (if needed):
```bash
dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet tool install --global dotnet-ef --version 9.0.10
dotnet add package Microsoft.EntityFrameworkCore.Design --version 9.0.10
```

3. Create the database and apply migrations:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ The focus here is to show what database schema (DDL) will be generated by EF Cor

2. Install the EF Core CLI tool (if needed):
```bash
dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet tool install --global dotnet-ef --version 9.0.10
dotnet add package Microsoft.EntityFrameworkCore.Design --version 9.0.10
```

3. Add a migration to generate the DDL (if not already present):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.5">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.10">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ The focus here is to show what database schema (DDL) will be generated by EF Cor

2. Install the EF Core CLI tool (if needed):
```bash
dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet tool install --global dotnet-ef --version 9.0.10
dotnet add package Microsoft.EntityFrameworkCore.Design --version 9.0.10
```

3. Add a migration to generate the DDL (if not already present):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.5">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.10">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ The focus here is to show what database schema (DDL) will be generated by EF Cor

2. Install the EF Core CLI tool (if needed):
```bash
dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet tool install --global dotnet-ef --version 9.0.10
dotnet add package Microsoft.EntityFrameworkCore.Design --version 9.0.10
```

3. Add a migration to generate the DDL (if not already present):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.5">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.10">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
3 changes: 3 additions & 0 deletions src/EFCore.Ydb/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
- Fixed bug: Missing/removed __EFMigrationsHistory caused INSERT errors (LockMigration); migrations now handle table recreation and locking properly ([#544](https://github.com/ydb-platform/ydb-dotnet-sdk/issues/544)).
- Added support for new YDB data types - `Date32`, `Datetime64`, `Timestamp64` and `Interval64`.
- Fixed bug: Missing `DEFAULT` clause generation in `YdbMigrationsSqlGenerator` (handles defaultValue/defaultValueSql) ([#552](https://github.com/ydb-platform/ydb-dotnet-sdk/issues/552)).
- Fixed bug: SqlQuery throws exception when using list parameters ([#540](https://github.com/ydb-platform/ydb-dotnet-sdk/issues/540)).
- Added support for the YDB retry policy (ADO.NET) and new configuration methods in `YdbDbContextOptionsBuilder`:
- `EnableRetryIdempotence()`: enables retries for errors classified as idempotent. You must ensure the operation itself is idempotent.
Expand Down
24 changes: 7 additions & 17 deletions src/EFCore.Ydb/src/Migrations/Internal/YdbHistoryRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public override async Task<IMigrationsDatabaseLock> AcquireDatabaseLockAsync(
{
await Dependencies.MigrationCommandExecutor.ExecuteNonQueryAsync(
AcquireDatabaseLockCommand(),
((IYdbRelationalConnection)Dependencies.Connection).Clone(), // TODO usage ExecutionContext
Dependencies.Connection,
new MigrationExecutionState(),
commitTransaction: true,
cancellationToken: cancellationToken
Expand Down Expand Up @@ -85,9 +85,7 @@ private async Task ReleaseDatabaseLockAsync()
try
{
await Dependencies.MigrationCommandExecutor.ExecuteNonQueryAsync(
ReleaseDatabaseLockCommand(),
((IYdbRelationalConnection)Dependencies.Connection).Clone()
).ConfigureAwait(false);
ReleaseDatabaseLockCommand(), Dependencies.Connection).ConfigureAwait(false);

return;
}
Expand All @@ -98,10 +96,8 @@ await Dependencies.MigrationCommandExecutor.ExecuteNonQueryAsync(
}
}

private IReadOnlyList<MigrationCommand> ReleaseDatabaseLockCommand() =>
Dependencies.MigrationsSqlGenerator.Generate(new List<MigrationOperation>
{ new SqlOperation { Sql = GetDeleteScript(LockKey) } }
);
private IReadOnlyList<MigrationCommand> ReleaseDatabaseLockCommand() => Dependencies.MigrationsSqlGenerator
.Generate(new List<MigrationOperation> { new SqlOperation { Sql = GetDeleteScript(LockKey) } });

bool IHistoryRepository.CreateIfNotExists() => CreateIfNotExistsAsync().GetAwaiter().GetResult();

Expand Down Expand Up @@ -135,13 +131,7 @@ await Dependencies.MigrationCommandExecutor.ExecuteNonQueryAsync(

private IReadOnlyList<MigrationCommand> GetCreateIfNotExistsCommands() =>
Dependencies.MigrationsSqlGenerator.Generate(new List<MigrationOperation>
{
new SqlOperation
{
Sql = GetCreateIfNotExistsScript(),
SuppressTransaction = true
}
});
{ new SqlOperation { Sql = GetCreateIfNotExistsScript(), SuppressTransaction = true } });

public override string GetCreateIfNotExistsScript()
=> GetCreateScript().Replace("CREATE TABLE", "CREATE TABLE IF NOT EXISTS");
Expand Down Expand Up @@ -179,8 +169,8 @@ private IReadOnlyList<MigrationCommand> SelectHistoryTableCommand() =>
{
new SqlOperation
{
Sql = $"SELECT * FROM {SqlGenerationHelper.DelimitIdentifier(TableName, TableSchema)}" +
$" WHERE '{MigrationIdColumnName}' = '{LockKey}';"
Sql = $"SELECT * FROM {SqlGenerationHelper.DelimitIdentifier(TableName, TableSchema)} " +
$"WHERE '{MigrationIdColumnName}' = CAST(RandomUuid(0) AS Text)"
}
});

Expand Down
5 changes: 5 additions & 0 deletions src/EFCore.Ydb/src/Migrations/YdbMigrationsSqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ MigrationCommandListBuilder builder
.Append(" ")
.Append(columnType)
.Append(operation.IsNullable ? string.Empty : " NOT NULL");

if (autoincrement == true)
return;

DefaultValue(operation.DefaultValue, operation.DefaultValueSql, columnType, builder);
}

protected override void CreateTablePrimaryKeyConstraint(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,21 @@
using System;
using Microsoft.EntityFrameworkCore.Storage;
using Ydb.Sdk.Ado.YdbType;

namespace EntityFrameworkCore.Ydb.Storage.Internal.Mapping;

// TODO: Await DateOnly support in Ydb.Sdk
public class YdbDateOnlyTypeMapping : RelationalTypeMapping
public class YdbDateOnlyTypeMapping : YdbTypeMapping
{
private const string DateOnlyFormatConst = "{0:yyyy-MM-dd}";

public YdbDateOnlyTypeMapping(string storeType)
: base(
new RelationalTypeMappingParameters(
new CoreTypeMappingParameters(typeof(DateOnly)),
storeType,
StoreTypePostfix.None,
System.Data.DbType.Date
)
)
public YdbDateOnlyTypeMapping(YdbDbType ydbDbType) : base(typeof(DateOnly), ydbDbType)
{
}

protected YdbDateOnlyTypeMapping(RelationalTypeMappingParameters parameters) : base(parameters)
private YdbDateOnlyTypeMapping(RelationalTypeMappingParameters parameters, YdbDbType ydbDbType)
: base(parameters, ydbDbType)
{
}

protected override YdbDateOnlyTypeMapping Clone(RelationalTypeMappingParameters parameters) => new(parameters);
protected override YdbDateOnlyTypeMapping Clone(RelationalTypeMappingParameters parameters) =>
new(parameters, YdbDbType);

protected override string GenerateNonNullSqlLiteral(object value)
{
var dateOnly = (DateOnly)value;
return $"Date('{dateOnly.ToString(DateOnlyFormatConst)}')";
}
protected override string SqlLiteralFormatString => $"{YdbDbType}('{{0:yyyy-MM-dd}}')";
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
using System.Data;
using Microsoft.EntityFrameworkCore.Storage;
using System;
using Ydb.Sdk.Ado.YdbType;

namespace EntityFrameworkCore.Ydb.Storage.Internal.Mapping;

public class YdbDateTimeTypeMapping(
string storeType,
DbType? dbType
) : DateTimeTypeMapping(storeType, dbType)
public class YdbDateTimeTypeMapping : YdbTypeMapping
{
private const string DateTimeFormatConst = @"{0:yyyy-MM-dd HH\:mm\:ss.fffffff}";
public YdbDateTimeTypeMapping(YdbDbType ydbDbType) : base(typeof(DateTime), ydbDbType)
{
}

private string StoreTypeLiteral { get; } = storeType;
private YdbDateTimeTypeMapping(RelationalTypeMappingParameters parameters, YdbDbType ydbDbType)
: base(parameters, ydbDbType)
{
}

protected override string SqlLiteralFormatString
=> "CAST('" + DateTimeFormatConst + $"' AS {StoreTypeLiteral})";
protected override YdbDateTimeTypeMapping Clone(RelationalTypeMappingParameters parameters) =>
new(parameters, YdbDbType);

protected override string SqlLiteralFormatString => YdbDbType switch
{
YdbDbType.Timestamp or YdbDbType.Timestamp64 => $@"{YdbDbType}('{{0:yyyy-MM-ddTHH\:mm\:ss.ffffffZ}}')",
YdbDbType.Datetime or YdbDbType.Datetime64 => $@"{YdbDbType}('{{0:yyyy-MM-ddTHH\:mm\:ssZ}}')",
YdbDbType.Date or YdbDbType.Date32 => $"{YdbDbType}('{{0:yyyy-MM-dd}}')",
_ => throw new ArgumentOutOfRangeException(nameof(YdbDbType), YdbDbType, null)
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Xml;
using Ydb.Sdk.Ado.YdbType;

namespace EntityFrameworkCore.Ydb.Storage.Internal.Mapping;

public class YdbTimeSpanTypeMapping : YdbTypeMapping
{
public YdbTimeSpanTypeMapping(YdbDbType ydbDbType) : base(typeof(TimeSpan), ydbDbType)
{
}

private YdbTimeSpanTypeMapping(RelationalTypeMappingParameters parameters, YdbDbType ydbDbType)
: base(parameters, ydbDbType)
{
}

protected override YdbTimeSpanTypeMapping Clone(RelationalTypeMappingParameters parameters) =>
new(parameters, YdbDbType);

protected override string GenerateNonNullSqlLiteral(object value) =>
$"{YdbDbType}('{XmlConvert.ToString((TimeSpan)value)}')";
}
41 changes: 41 additions & 0 deletions src/EFCore.Ydb/src/Storage/Internal/Mapping/YdbTypeMapping.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.Data.Common;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.Json;
using Ydb.Sdk.Ado;
using Ydb.Sdk.Ado.YdbType;

namespace EntityFrameworkCore.Ydb.Storage.Internal.Mapping;

public abstract class YdbTypeMapping(
RelationalTypeMapping.RelationalTypeMappingParameters parameters,
YdbDbType ydbDbType
) : RelationalTypeMapping(parameters), IYdbTypeMapping
{
public YdbDbType YdbDbType { get; } = ydbDbType;

protected YdbTypeMapping(
Type clrType,
YdbDbType ydbDbType,
JsonValueReaderWriter? jsonValueReaderWriter = null
) : this(
new RelationalTypeMappingParameters(
new CoreTypeMappingParameters(clrType, jsonValueReaderWriter: jsonValueReaderWriter),
ydbDbType.ToString()
), ydbDbType
)
{
}

protected override void ConfigureParameter(DbParameter parameter)
{
if (parameter is not YdbParameter ydbParameter)
{
throw new InvalidOperationException(
$"Ydb-specific type mapping {GetType().Name} being used with non-Ydb parameter type {parameter.GetType().Name}");
}

base.ConfigureParameter(parameter);
ydbParameter.YdbDbType = YdbDbType;
}
}
Loading
Loading