Skip to content

Commit

Permalink
Changes as decribed in the log.
Browse files Browse the repository at this point in the history
  • Loading branch information
chullybun committed Mar 3, 2024
1 parent 500c274 commit bc6a004
Show file tree
Hide file tree
Showing 91 changed files with 1,299 additions and 246 deletions.
19 changes: 18 additions & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -308,4 +308,21 @@ jobs:

- name: Template/HttpAgent test
working-directory: ./Foo.Ha.Bar
run: dotnet test
run: dotnet test

# Template - Sql Server with Entity Framework and Azure Functions Service

- name: Template/SqlServer/SpWs create
run: dotnet new beef --company Foo.SpWs --appname Bar --datasource SqlServerProcs --output Foo.SpWs.Bar

- name: Template/SqlServer/SpWs database
working-directory: ./Foo.SpWs.Bar/Foo.SpWs.Bar.Database
run: dotnet run dropandall --connection-varname Bar_ConnectionStrings__Database --accept-prompts

- name: Template/SqlServer/SpWs code-gen
working-directory: ./Foo.SpWs.Bar/Foo.SpWs.Bar.CodeGen
run: dotnet run all

- name: Template/SqlServer/SpWs test
working-directory: ./Foo.SpWs.Bar
run: dotnet test
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

Represents the **NuGet** versions.

## v5.11.0
- *Enhancement:* Added `dotnet new beef ... --services AzFunction` to enable the templating of a corresponding `Company.AppName.Services` project as an Azure Functions project. This will provide an example of leveraging the shared `Company.AppName.Business` logic and consuming the published events using an `EventSubscriberOrchestrator`.
- *Enhancement:* The `DatabaseMapper` (stored procedures) code-generation logic has been updated to leverage the new extended `DatabaseMapperEx`. This avoids the existing reflection and expression compilation, using explicit code to perform the mapping. Can offer up to 40%+ improvement in some scenarios. Where existing behavior is required then set YAML `databaseMapperEx: false` in the `entity.beef-5.yaml` file (root and/or entity within hierarchy).

## v5.10.0
- *Enhancement:* Added [PostgreSQL](https://www.postgresql.org/) database support:
- Leverages both `CoreEx.Database.Postgres` (runtime) and `DbEx.Postgres` (migration) packages; encapsulates the `Npgsql` package.
Expand Down
3 changes: 2 additions & 1 deletion docs/Entity-CodeGeneration-Config.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ Property | Description
-|-
**`databaseName`** | The .NET database interface name (used where `Operation.AutoImplement` is `Database`).<br/>&dagger; Defaults to `IDatabase`. This can be overridden within the `Entity`(s).
**`databaseSchema`** | The default database schema name.<br/>&dagger; Defaults to `dbo`.
**`databaseProvider`** | The default database schema name. Valid options are: `SqlServer`, `MySQL`.<br/>&dagger; Defaults to `SqlServer`. Enables specific database provider functionality/formatting/etc. where applicable.
**`databaseProvider`** | The default database schema name. Valid options are: `SqlServer`, `MySQL`, `Postgres`.<br/>&dagger; Defaults to `SqlServer`. Enables specific database provider functionality/formatting/etc. where applicable.
`databaseMapperEx` | Indicates that a `DatabaseMapperEx` will be used; versus, `DatabaseMapper` (which uses Reflection internally).<br/>&dagger; Defaults to `true`. The `DatabaseMapperEx` essentially replaces the `DatabaseMapper` as it is more performant (extended/explicit); this option can be used where leagcy/existing behavior is required.

<br/>

Expand Down
1 change: 1 addition & 0 deletions docs/Entity-Entity-Config.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ Property | Description
**`databaseSchema`** | The database schema name (used where `AutoImplement` is `Database`).<br/>&dagger; Defaults to `dbo`.
`databaseMapperInheritsFrom` | The name of the `Mapper` that the generated Database `Mapper` inherits from.
`databaseCustomerMapper` | Indicates that a custom Database `Mapper` will be used; i.e. not generated.<br/>&dagger; Otherwise, by default, a `Mapper` will be generated.
`databaseMapperEx` | Indicates that a `DatabaseMapperEx` (extended/explicit) will be used; versus, `DatabaseMapper` (which uses Reflection internally).<br/>&dagger; Defaults to `CodeGeneration.DatabaseMapperEx` (its default value is `true`). The `DatabaseMapperEx` essentially replaces the `DatabaseMapper` as it is more performant; this option can be used where leagcy/existing behavior is required.

<br/>

Expand Down
2 changes: 1 addition & 1 deletion samples/Cdr.Banking/Cdr.Banking.Api/Cdr.Banking.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<ImplicitUsings>true</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CoreEx.AspNetCore" Version="3.12.0" />
<PackageReference Include="CoreEx.AspNetCore" Version="3.13.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.5.0" />
</ItemGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
<Folder Include="DataSvc\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CoreEx.AspNetCore" Version="3.12.0" />
<PackageReference Include="CoreEx.Cosmos" Version="3.12.0" />
<PackageReference Include="CoreEx.Validation" Version="3.12.0" />
<PackageReference Include="CoreEx.AspNetCore" Version="3.13.0" />
<PackageReference Include="CoreEx.Cosmos" Version="3.13.0" />
<PackageReference Include="CoreEx.Validation" Version="3.13.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
<Folder Include="Entities\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CoreEx" Version="3.12.0" />
<PackageReference Include="CoreEx" Version="3.13.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="CoreEx.UnitTesting.NUnit" Version="3.12.0" />
<PackageReference Include="CoreEx.UnitTesting.NUnit" Version="3.13.0" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion samples/Demo/Beef.Demo.Api/Beef.Demo.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CoreEx.AspNetCore" Version="3.12.0" />
<PackageReference Include="CoreEx.AspNetCore" Version="3.13.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="6.5.0" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,17 @@ public Task<IActionResult> PatchWithEf(Guid id)
[ProducesResponseType((int)HttpStatusCode.NoContent)]
public Task<IActionResult> GetDocumentation(Guid id)
=> _webApi.GetAsync<FileContentResult>(Request, p => _manager.GetDocumentationAsync(id), alternateStatusCode: HttpStatusCode.NoContent, operationType: CoreEx.OperationType.Unspecified);

/// <summary>
/// Simulate Work.
/// </summary>
/// <param name="id">The <see cref="Person"/> identifier.</param>
/// <returns>A resultant <see cref="string"/>.</returns>
[HttpGet("api/v1/persons/simulate")]
[ProducesResponseType(typeof(string), (int)HttpStatusCode.OK)]
[ProducesResponseType((int)HttpStatusCode.NoContent)]
public Task<IActionResult> SimulateWork(Guid id)
=> _webApi.GetWithResultAsync<string?>(Request, p => _manager.SimulateWorkAsync(id), alternateStatusCode: HttpStatusCode.NoContent, operationType: CoreEx.OperationType.Unspecified);
}

#pragma warning restore
Expand Down
16 changes: 8 additions & 8 deletions samples/Demo/Beef.Demo.Business/Beef.Demo.Business.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="CoreEx" Version="3.12.0" />
<PackageReference Include="CoreEx.AspNetCore" Version="3.12.0" />
<PackageReference Include="CoreEx.Cosmos" Version="3.12.0" />
<PackageReference Include="CoreEx.Database" Version="3.12.0" />
<PackageReference Include="CoreEx.Database.SqlServer" Version="3.12.0" />
<PackageReference Include="CoreEx.EntityFrameworkCore" Version="3.12.0" />
<PackageReference Include="CoreEx.Validation" Version="3.12.0" />
<PackageReference Include="CoreEx.FluentValidation" Version="3.12.0" />
<PackageReference Include="CoreEx" Version="3.13.0" />
<PackageReference Include="CoreEx.AspNetCore" Version="3.13.0" />
<PackageReference Include="CoreEx.Cosmos" Version="3.13.0" />
<PackageReference Include="CoreEx.Database" Version="3.13.0" />
<PackageReference Include="CoreEx.Database.SqlServer" Version="3.13.0" />
<PackageReference Include="CoreEx.EntityFrameworkCore" Version="3.13.0" />
<PackageReference Include="CoreEx.Validation" Version="3.13.0" />
<PackageReference Include="CoreEx.FluentValidation" Version="3.13.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.20" />
</ItemGroup>

Expand Down
27 changes: 17 additions & 10 deletions samples/Demo/Beef.Demo.Business/Data/Generated/AddressData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,26 @@ public partial class AddressData
/// <summary>
/// Provides the <see cref="Address"/> property and database column mapping.
/// </summary>
public partial class DbMapper : DatabaseMapper<Address, DbMapper>
public partial class DbMapper : DatabaseMapperEx<Address, DbMapper>
{
/// <summary>
/// Initializes a new instance of the <see cref="DbMapper"/> class.
/// </summary>
public DbMapper()
/// <inheritdoc />
protected override void OnMapToDb(Address value, DatabaseParameterCollection parameters, OperationTypes operationType)
{
parameters.AddParameter("Street", value.Street);
parameters.AddParameter("City", value.City);
OnMapToDbEx(value, parameters, operationType);
}

/// <inheritdoc />
protected override void OnMapFromDb(DatabaseRecord record, Address value, OperationTypes operationType)
{
Property(s => s.Street);
Property(s => s.City);
DbMapperCtor();
value.Street = record.GetValue<string?>("Street");
value.City = record.GetValue<string?>("City");
OnMapFromDbEx(record, value, operationType);
}

partial void DbMapperCtor(); // Enables the DbMapper constructor to be extended.

partial void OnMapToDbEx(Address value, DatabaseParameterCollection parameters, OperationTypes operationType); // Enables the DbMapper.OnMapToDb to be extended.
partial void OnMapFromDbEx(DatabaseRecord record, Address value, OperationTypes operationType); // Enables the DbMapper.OnMapFromDb to be extended.
}

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions samples/Demo/Beef.Demo.Business/Data/Generated/ContactData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public EntityToModelEfMapper()
Map((s, d) => d.FirstName = s.FirstName, OperationTypes.Any, s => s.FirstName == default, d => d.FirstName = default);
Map((s, d) => d.LastName = s.LastName, OperationTypes.Any, s => s.LastName == default, d => d.LastName = default);
Map((s, d) => d.StatusCode = s.StatusSid, OperationTypes.Any, s => s.StatusSid == default, d => d.StatusCode = default);
Map((s, d) => d.Comms = ObjectToJsonConverter<ContactCommCollection>.Default.ToDestination.Convert(s.Communications), OperationTypes.Any, s => s.Communications == default, d => d.Comms = default);
Map((s, d) => d.Comms = ObjectToJsonConverter<ContactCommCollection>.Default.ConvertToDestination(s.Communications), OperationTypes.Any, s => s.Communications == default, d => d.Comms = default);
EntityToModelEfMapperCtor();
}

Expand All @@ -98,7 +98,7 @@ public ModelToEntityEfMapper()
Map((s, d) => d.FirstName = (string?)s.FirstName!, OperationTypes.Any, s => s.FirstName == default, d => d.FirstName = default);
Map((s, d) => d.LastName = (string?)s.LastName!, OperationTypes.Any, s => s.LastName == default, d => d.LastName = default);
Map((s, d) => d.StatusSid = (string?)s.StatusCode!, OperationTypes.Any, s => s.StatusCode == default, d => d.StatusSid = default);
Map((s, d) => d.Communications = (ContactCommCollection?)ObjectToJsonConverter<ContactCommCollection>.Default.ToSource.Convert(s.Comms!), OperationTypes.Any, s => s.Comms == default, d => d.Communications = default);
Map((s, d) => d.Communications = (ContactCommCollection?)ObjectToJsonConverter<ContactCommCollection>.Default.ConvertToSource(s.Comms!), OperationTypes.Any, s => s.Comms == default, d => d.Communications = default);
ModelToEntityEfMapperCtor();
}

Expand Down
57 changes: 40 additions & 17 deletions samples/Demo/Beef.Demo.Business/Data/Generated/GenderData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,49 @@ public Task<Result<Gender>> UpdateAsync(Gender value)
/// <summary>
/// Provides the <see cref="Gender"/> property and database column mapping.
/// </summary>
public partial class DbMapper : DatabaseMapper<Gender, DbMapper>
public partial class DbMapper : DatabaseMapperEx<Gender, DbMapper>
{
/// <summary>
/// Initializes a new instance of the <see cref="DbMapper"/> class.
/// </summary>
public DbMapper()
/// <inheritdoc />
protected override void OnMapToDb(Gender value, DatabaseParameterCollection parameters, OperationTypes operationType)
{
Property(s => s.Id, "GenderId").SetPrimaryKey(true);
Property(s => s.Code);
Property(s => s.Text);
Property(s => s.IsActive);
Property(s => s.SortOrder);
Property(s => s.AlternateName);
Property(s => s.TripCode);
Property(s => s.Country, "CountryId").SetConverter(ReferenceDataIdConverter<RefDataNamespace.Country, Guid?>.Default);
Property(s => s.ETag, "RowVersion", operationTypes: OperationTypes.AnyExceptCreate).SetConverter(StringToBase64Converter.Default);
DbMapperCtor();
parameters.AddParameter("GenderId", value.Id).SetDirectionToOutputOnCreate(operationType);
parameters.AddParameter("Code", value.Code);
parameters.AddParameter("Text", value.Text);
parameters.AddParameter("IsActive", value.IsActive);
parameters.AddParameter("SortOrder", value.SortOrder);
parameters.AddParameter("AlternateName", value.AlternateName);
parameters.AddParameter("TripCode", value.TripCode);
parameters.AddParameter("CountryId", ReferenceDataIdConverter<RefDataNamespace.Country, Guid?>.Default.ConvertToDestination(value.Country));
WhenAnyExceptCreate(operationType, () => parameters.AddParameter(parameters.Database.DatabaseColumns.RowVersionName, StringToBase64Converter.Default.ConvertToDestination(value.ETag)));
OnMapToDbEx(value, parameters, operationType);
}

partial void DbMapperCtor(); // Enables the DbMapper constructor to be extended.

/// <inheritdoc />
protected override void OnMapFromDb(DatabaseRecord record, Gender value, OperationTypes operationType)
{
value.Id = record.GetValue<Guid>("GenderId");
value.Code = record.GetValue<string?>("Code");
value.Text = record.GetValue<string?>("Text");
value.IsActive = record.GetValue<bool>("IsActive");
value.SortOrder = record.GetValue<int>("SortOrder");
value.AlternateName = record.GetValue<string?>("AlternateName");
value.TripCode = record.GetValue<string?>("TripCode");
value.Country = (RefDataNamespace.Country?)ReferenceDataIdConverter<RefDataNamespace.Country, Guid?>.Default.ConvertToSource(record.GetValue("CountryId"));
WhenAnyExceptCreate(operationType, () => value.ETag = (string?)StringToBase64Converter.Default.ConvertToSource(record.GetValue(record.Database.DatabaseColumns.RowVersionName)));
OnMapFromDbEx(record, value, operationType);
}

/// <inheritdoc />
protected override void OnMapKeyToDb(CompositeKey key, DatabaseParameterCollection parameters)
{
key.AssertLength(1);
parameters.AddParameter("GenderId", key.Args[0]);
OnMapKeyToDbEx(key, parameters);
}

partial void OnMapToDbEx(Gender value, DatabaseParameterCollection parameters, OperationTypes operationType); // Enables the DbMapper.OnMapToDb to be extended.
partial void OnMapFromDbEx(DatabaseRecord record, Gender value, OperationTypes operationType); // Enables the DbMapper.OnMapFromDb to be extended.
partial void OnMapKeyToDbEx(CompositeKey key, DatabaseParameterCollection parameters); // Enables the DbMapper.OnMapKeyToDb to be extended.
}
}

Expand Down
7 changes: 7 additions & 0 deletions samples/Demo/Beef.Demo.Business/Data/Generated/IPersonData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,13 @@ public partial interface IPersonData
/// <param name="id">The <see cref="Person"/> identifier.</param>
/// <returns>A resultant <see cref="FileContentResult"/>.</returns>
Task<FileContentResult> GetDocumentationAsync(Guid id);

/// <summary>
/// Simulate Work.
/// </summary>
/// <param name="id">The <see cref="Person"/> identifier.</param>
/// <returns>A resultant <see cref="string"/>.</returns>
Task<Result<string?>> SimulateWorkAsync(Guid id);
}

#pragma warning restore
Expand Down
Loading

0 comments on commit bc6a004

Please sign in to comment.