Just updated all the things and had to fix a bunch of stuff to get rid of the compiler errors, haven't run anything yet, just got it to compile at this point.

This commit is contained in:
2019-10-15 23:31:17 +00:00
parent a431ca32f6
commit aa177f4d48
10 changed files with 176 additions and 97 deletions

View File

@@ -8,6 +8,8 @@ Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOiIxNTYxNDk4NzQ4IiwiZXhwIjoi
UPDATE all the things before commencing work UPDATE all the things before commencing work
- https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.0&tabs=visual-studio-code - https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.0&tabs=visual-studio-code
- https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/breaking-changes - https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/breaking-changes
- https://github.com/domaindrivendev/Swashbuckle.AspNetCore#swashbuckleaspnetcoreannotations
-
Need a sprint to get to a fully testable client with entry form, list and as much as possible all features from COMMON-* specs list Need a sprint to get to a fully testable client with entry form, list and as much as possible all features from COMMON-* specs list
Do the stuff in the Client todo first then back to the server as required. Do the stuff in the Client todo first then back to the server as required.

View File

@@ -31,13 +31,23 @@
<PackageReference Include="jose-jwt" Version="2.4.0" /> <PackageReference Include="jose-jwt" Version="2.4.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.0-preview1.19508.20" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.0-preview1.19508.20" />
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="3.1.0-preview1.19508.20" /> <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="3.1.0-preview1.19508.20" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.0-preview1.19508.20" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="4.0.0-preview8.19405.7" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="4.0.0-preview8.19405.7" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="4.0.0-preview8.19405.7" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="4.0.0-preview8.19405.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.0-preview1.19506.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.0-preview1.19506.2" />
<PackageReference Include="Microsoft.Extensions.ApiDescription.Server" Version="3.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.OpenApi" Version="1.1.4" />
<PackageReference Include="NLog" Version="4.6.7" /> <PackageReference Include="NLog" Version="4.6.7" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.9.0" /> <PackageReference Include="NLog.Web.AspNetCore" Version="4.9.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.0.1" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc4" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc4" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="5.0.0-rc4" />
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="5.0.0-rc4" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="5.0.0-rc4" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUi" Version="5.0.0-rc4" />
</ItemGroup> </ItemGroup>
<Target Name="CopyCustomContent" AfterTargets="AfterBuild"> <Target Name="CopyCustomContent" AfterTargets="AfterBuild">

View File

@@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.ApiExplorer; using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
@@ -11,6 +12,9 @@ using Microsoft.IdentityModel.Tokens;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.OpenApi.Models;
using AyaNova.Models; using AyaNova.Models;
using AyaNova.Util; using AyaNova.Util;
using AyaNova.Generator; using AyaNova.Generator;
@@ -24,7 +28,8 @@ using System.IO;
using System.Reflection; using System.Reflection;
using System.Linq; using System.Linq;
using System; using System;
using System.Collections.Generic;
using Newtonsoft.Json.Serialization;
namespace AyaNova namespace AyaNova
@@ -36,7 +41,7 @@ namespace AyaNova
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
// //
public Startup(ILogger<Startup> logger, ILoggerFactory logFactory, Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnvironment) public Startup(ILogger<Startup> logger, ILoggerFactory logFactory, Microsoft.AspNetCore.Hosting.IWebHostEnvironment hostingEnvironment)
{ {
_log = logger; _log = logger;
_hostingEnvironment = hostingEnvironment; _hostingEnvironment = hostingEnvironment;
@@ -48,7 +53,7 @@ namespace AyaNova
private readonly ILogger<Startup> _log; private readonly ILogger<Startup> _log;
private string _connectionString = ""; private string _connectionString = "";
private readonly Microsoft.AspNetCore.Hosting.IHostingEnvironment _hostingEnvironment; private readonly Microsoft.AspNetCore.Hosting.IWebHostEnvironment _hostingEnvironment;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// This method gets called by the runtime. Use this method to add services to the container. // This method gets called by the runtime. Use this method to add services to the container.
@@ -57,14 +62,23 @@ namespace AyaNova
{ {
_log.LogDebug("BOOT: initializing services..."); _log.LogDebug("BOOT: initializing services...");
//Server state service for shutting people out of api //Server state service for shutting people out of api
_log.LogDebug("BOOT: init ApiServerState service"); _log.LogDebug("BOOT: init ApiServerState service");
services.AddSingleton(new AyaNova.Api.ControllerHelpers.ApiServerState()); services.AddSingleton(new AyaNova.Api.ControllerHelpers.ApiServerState());
//Init mvc
_log.LogDebug("BOOT: init MVC Core service");
var mvc = services.AddMvcCore();
_log.LogDebug("BOOT: add json service");
mvc.AddNewtonsoftJson();
// add the versioned api explorer, which also adds IApiVersionDescriptionProvider service // add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
// note: the specified format code will format the version as "'v'major[.minor][-status]" // note: the specified format code will format the version as "'v'major[.minor][-status]"
_log.LogDebug("BOOT: init ApiExplorer service"); _log.LogDebug("BOOT: init ApiExplorer service");
services.AddMvcCore().AddVersionedApiExplorer(o => o.GroupNameFormat = "'v'VVV"); services.AddVersionedApiExplorer(o => o.GroupNameFormat = "'v'VVV");
_log.LogDebug("BOOT: ensuring user and backup folders exist and are separate locations..."); _log.LogDebug("BOOT: ensuring user and backup folders exist and are separate locations...");
FileUtil.EnsureUserAndUtilityFoldersExistAndAreNotIdentical(_hostingEnvironment.ContentRootPath); FileUtil.EnsureUserAndUtilityFoldersExistAndAreNotIdentical(_hostingEnvironment.ContentRootPath);
@@ -98,7 +112,7 @@ namespace AyaNova
bool LOG_SENSITIVE_DATA = false; bool LOG_SENSITIVE_DATA = false;
#if (DEBUG) #if (DEBUG)
// LOG_SENSITIVE_DATA = true; // LOG_SENSITIVE_DATA = true;
#endif #endif
@@ -110,7 +124,8 @@ namespace AyaNova
)//http://www.npgsql.org/efcore/misc.html?q=execution%20strategy#execution-strategy )//http://www.npgsql.org/efcore/misc.html?q=execution%20strategy#execution-strategy
.ConfigureWarnings(warnings => //https://livebook.manning.com/#!/book/entity-framework-core-in-action/chapter-12/v-10/85 .ConfigureWarnings(warnings => //https://livebook.manning.com/#!/book/entity-framework-core-in-action/chapter-12/v-10/85
warnings.Throw( //Throw an exception on client eval, not necessarily an error but a smell warnings.Throw( //Throw an exception on client eval, not necessarily an error but a smell
Microsoft.EntityFrameworkCore.Diagnostics.RelationalEventId.QueryClientEvaluationWarning)) // Microsoft.EntityFrameworkCore.Diagnostics.RelationalEventId.QueryClientEvaluationWarning
))
.EnableSensitiveDataLogging(LOG_SENSITIVE_DATA) .EnableSensitiveDataLogging(LOG_SENSITIVE_DATA)
); );
@@ -154,7 +169,9 @@ namespace AyaNova
}).AddMetrics().AddJsonOptions(options => }).AddMetrics().AddJsonOptions(options =>
{ {
options.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc; //2019-10-15 - removed this due to fuckery after update, is it required??? Not sure at this point
//if metrics have wrong dates then it's important I guess
//options.JsonSerializerOptions.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
}); });
@@ -179,29 +196,55 @@ namespace AyaNova
} }
// add a custom operation filter which sets default values // add a custom operation filter which sets default values
c.OperationFilter<SwaggerDefaultValues>(); //Removed because will no longer compile the SwaggerDefaultValues but may be needed, not sure it's all a bit muddled
// c.OperationFilter<SwaggerDefaultValues>();
// integrate xml comments // integrate xml comments
c.IncludeXmlComments(XmlCommentsFilePath); c.IncludeXmlComments(XmlCommentsFilePath);
//2019-10-15 - Removed this because apikeyscheme is no longer recognized and it appears it *may* not be necessary... TWT
//If I have any issues with bearer tokens in swagger then this is probably necessary but in a new way
//this is required to allow authentication when testing secure routes via swagger UI //this is required to allow authentication when testing secure routes via swagger UI
c.AddSecurityDefinition("Bearer", new ApiKeyScheme // c.AddSecurityDefinition("Bearer", new ApiKeyScheme
{ // {
Description = "JWT Authorization header using the Bearer scheme. Get your token by logging in via the Auth route then enter it here with the \"Bearer \" prefix. Example: \"Bearer {token}\"", // Description = "JWT Authorization header using the Bearer scheme. Get your token by logging in via the Auth route then enter it here with the \"Bearer \" prefix. Example: \"Bearer {token}\"",
Name = "Authorization", // Name = "Authorization",
In = "header", // In = "header",
Type = "apiKey" // Type = "apiKey"
}); // });
c.AddSecurityRequirement(new System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>>
//Obsolete way
// c.AddSecurityRequirement(new System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>>
// {
// { "Bearer", new string[] { } }
// });
//https://stackoverflow.com/questions/56234504/migrating-to-swashbuckle-aspnetcore-version-5
//First we define the security scheme
c.AddSecurityDefinition("Bearer", //Name the security scheme
new OpenApiSecurityScheme
{ {
{ "Bearer", new string[] { } } Description = "JWT Authorization header using the Bearer scheme.",
Type = SecuritySchemeType.Http, //We set the scheme type to http since we're using bearer authentication
Scheme = "bearer" //The name of the HTTP Authorization scheme to be used in the Authorization header. In this case "bearer".
}); });
c.AddSecurityRequirement(new OpenApiSecurityRequirement{
{
new OpenApiSecurityScheme{
Reference = new OpenApiReference{
Id = "Bearer", //The name of the previously defined security scheme.
Type = ReferenceType.SecurityScheme
}
},new List<string>()
}
});
}); });
@@ -275,7 +318,7 @@ namespace AyaNova
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
// //
public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment env, public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IWebHostEnvironment env,
AyContext dbContext, IApiVersionDescriptionProvider provider, AyaNova.Api.ControllerHelpers.ApiServerState apiServerState, IServiceProvider serviceProvider) AyContext dbContext, IApiVersionDescriptionProvider provider, AyaNova.Api.ControllerHelpers.ApiServerState apiServerState, IServiceProvider serviceProvider)
{ {
_log.LogDebug("BOOT: configuring request pipeline..."); _log.LogDebug("BOOT: configuring request pipeline...");
@@ -478,9 +521,9 @@ namespace AyaNova
} }
} }
static Info CreateInfoForApiVersion(ApiVersionDescription description) static Microsoft.OpenApi.Models.OpenApiInfo CreateInfoForApiVersion(ApiVersionDescription description)
{ {
var info = new Info() var info = new Microsoft.OpenApi.Models.OpenApiInfo()
{ {
Title = $"AyaNova API {description.ApiVersion}", Title = $"AyaNova API {description.ApiVersion}",
Version = description.ApiVersion.ToString() Version = description.ApiVersion.ToString()

View File

@@ -1,47 +1,47 @@
namespace AyaNova // namespace AyaNova
{ // {
using Swashbuckle.AspNetCore.Swagger; // using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerGen; // using System.Linq;
using System.Linq;
/// <summary>
/// Represents the Swagger/Swashbuckle operation filter used to document the implicit API version parameter.
/// </summary>
/// <remarks>This <see cref="IOperationFilter"/> is only required due to bugs in the <see cref="SwaggerGenerator"/>.
/// Once they are fixed and published, this class can be removed.</remarks>
public class SwaggerDefaultValues : IOperationFilter
{
/// <summary>
/// Applies the filter to the specified operation using the given context.
/// </summary>
/// <param name="operation">The operation to apply the filter to.</param>
/// <param name="context">The current operation filter context.</param>
public void Apply( Operation operation, OperationFilterContext context )
{
// REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/412
// REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/413
foreach ( var parameter in operation.Parameters.OfType<NonBodyParameter>() )
{
var description = context.ApiDescription.ParameterDescriptions.First( p => p.Name == parameter.Name );
var routeInfo = description.RouteInfo;
if ( parameter.Description == null ) // /// <summary>
{ // /// Represents the Swagger/Swashbuckle operation filter used to document the implicit API version parameter.
parameter.Description = description.ModelMetadata?.Description; // /// </summary>
} // /// <remarks>This <see cref="IOperationFilter"/> is only required due to bugs in the <see cref="SwaggerGenerator"/>.
// /// Once they are fixed and published, this class can be removed.</remarks>
// public class SwaggerDefaultValues : IOperationFilter
// {
// /// <summary>
// /// Applies the filter to the specified operation using the given context.
// /// </summary>
// /// <param name="operation">The operation to apply the filter to.</param>
// /// <param name="context">The current operation filter context.</param>
// public void Apply( Operation operation, OperationFilterContext context )
// {
// // REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/412
// // REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/413
// foreach ( var parameter in operation.Parameters.OfType<NonBodyParameter>() )
// {
// var description = context.ApiDescription.ParameterDescriptions.First( p => p.Name == parameter.Name );
// var routeInfo = description.RouteInfo;
if ( routeInfo == null ) // if ( parameter.Description == null )
{ // {
continue; // parameter.Description = description.ModelMetadata?.Description;
} // }
if ( parameter.Default == null ) // if ( routeInfo == null )
{ // {
parameter.Default = routeInfo.DefaultValue; // continue;
} // }
parameter.Required |= !routeInfo.IsOptional; // if ( parameter.Default == null )
} // {
} // parameter.Default = routeInfo.DefaultValue;
} // }
}
// parameter.Required |= !routeInfo.IsOptional;
// }
// }
// }
// }

View File

@@ -40,7 +40,7 @@ namespace AyaNova.Biz
/// <param name="ct"></param> /// <param name="ct"></param>
internal static void DeleteObject(long userId, AyaType ayType, long ayId, string textra, AyContext ct) internal static void DeleteObject(long userId, AyaType ayType, long ayId, string textra, AyContext ct)
{ {
ct.Database.ExecuteSqlCommand($"delete from aevent where aytype = {ayType} and ayid={ayId}"); ct.Database.ExecuteSqlInterpolated($"delete from aevent where aytype = {ayType} and ayid={ayId}");
ct.Event.Add(new Event(userId, ayId, ayType, AyaEvent.Deleted, textra)); ct.Event.Add(new Event(userId, ayId, ayType, AyaEvent.Deleted, textra));
} }

View File

@@ -217,11 +217,17 @@ namespace AyaNova.Biz
/// <param name="jobIdToBeDeleted"></param> /// <param name="jobIdToBeDeleted"></param>
private static async Task removeJobAndLogsAsync(AyContext ct, Guid jobIdToBeDeleted) private static async Task removeJobAndLogsAsync(AyContext ct, Guid jobIdToBeDeleted)
{ {
//delete logs // //delete logs
await ct.Database.ExecuteSqlCommandAsync("delete from aopsjoblog where jobid = {0}", new object[] { jobIdToBeDeleted }); // await ct.Database.ExecuteSqlCommandAsync("delete from aopsjoblog where jobid = {0}", new object[] { jobIdToBeDeleted });
// //delete the job
// await ct.Database.ExecuteSqlCommandAsync("delete from aopsjob where gid = {0}", new object[] { jobIdToBeDeleted });
//delete logs
await ct.Database.ExecuteSqlInterpolatedAsync($"delete from aopsjoblog where jobid = {jobIdToBeDeleted}");
//delete the job //delete the job
await ct.Database.ExecuteSqlCommandAsync("delete from aopsjob where gid = {0}", new object[] { jobIdToBeDeleted }); await ct.Database.ExecuteSqlInterpolatedAsync($"delete from aopsjob where gid = {jobIdToBeDeleted}");
} }

View File

@@ -452,7 +452,7 @@ namespace AyaNova.Biz
//Be careful in future, if you put ToString at the end of each object in the string interpolation //Be careful in future, if you put ToString at the end of each object in the string interpolation
//npgsql driver will assume it's a string and put quotes around it triggering an error that a string can't be compared to an int //npgsql driver will assume it's a string and put quotes around it triggering an error that a string can't be compared to an int
AyContext ct = ServiceProviderProvider.DBContext; AyContext ct = ServiceProviderProvider.DBContext;
ct.Database.ExecuteSqlCommand($"delete from asearchkey where objectid={objectID} and objecttype={(int)objectType}"); ct.Database.ExecuteSqlInterpolated($"delete from asearchkey where objectid={objectID} and objecttype={(int)objectType}");
} }

View File

@@ -205,18 +205,29 @@ namespace AyaNova.Biz
#pragma warning disable EF1000 #pragma warning disable EF1000
// var items = await ct.User
// .AsNoTracking()
// .FromSql(q)
// .Skip(pagingOptions.Offset.Value)
// .Take(pagingOptions.Limit.Value)
// .ToArrayAsync();
var items = await ct.User var items = await ct.User
.AsNoTracking() .FromSqlRaw(q)
.FromSql(q) .AsNoTracking()
.Skip(pagingOptions.Offset.Value) .Skip(pagingOptions.Offset.Value)
.Take(pagingOptions.Limit.Value) .Take(pagingOptions.Limit.Value)
.ToArrayAsync(); .ToArrayAsync();
var totalRecordCount = await ct.User // var totalRecordCount = await ct.User
.AsNoTracking() // .AsNoTracking()
.FromSql(q) // .FromSql(q)
.CountAsync(); // .CountAsync();
var totalRecordCount = await ct.User.FromSqlRaw(q)
.AsNoTracking()
.CountAsync();
#pragma warning restore EF1000 #pragma warning restore EF1000
int itemCount = items.Count();//totalRecordCount doesn't skip and take so not usable here int itemCount = items.Count();//totalRecordCount doesn't skip and take so not usable here
@@ -364,7 +375,7 @@ namespace AyaNova.Biz
//Delete sibling objects //Delete sibling objects
//USEROPTIONS //USEROPTIONS
ct.Database.ExecuteSqlCommand($"delete from auseroptions where userid={dbObj.Id}"); ct.Database.ExecuteSqlInterpolated($"delete from auseroptions where userid={dbObj.Id}");
EventLogProcessor.DeleteObject(UserId, BizType, dbObj.Id, dbObj.Name, ct); EventLogProcessor.DeleteObject(UserId, BizType, dbObj.Id, dbObj.Name, ct);

View File

@@ -90,7 +90,7 @@ namespace AyaNova.Biz
outObj.Serial = ServerBootConfig.WIDGET_SERIAL.GetNext(); outObj.Serial = ServerBootConfig.WIDGET_SERIAL.GetNext();
outObj.Tags = TagUtil.NormalizeTags(outObj.Tags); outObj.Tags = TagUtil.NormalizeTags(outObj.Tags);
outObj.CustomFields=JsonUtil.CompactJson(outObj.CustomFields); outObj.CustomFields = JsonUtil.CompactJson(outObj.CustomFields);
await ct.Widget.AddAsync(outObj); await ct.Widget.AddAsync(outObj);
await ct.SaveChangesAsync(); await ct.SaveChangesAsync();
@@ -118,7 +118,7 @@ namespace AyaNova.Biz
//Test get serial id visible id number from generator //Test get serial id visible id number from generator
outObj.Serial = ServerBootConfig.WIDGET_SERIAL.GetNext(); outObj.Serial = ServerBootConfig.WIDGET_SERIAL.GetNext();
outObj.Tags = TagUtil.NormalizeTags(outObj.Tags); outObj.Tags = TagUtil.NormalizeTags(outObj.Tags);
outObj.CustomFields=JsonUtil.CompactJson(outObj.CustomFields); outObj.CustomFields = JsonUtil.CompactJson(outObj.CustomFields);
TempContext.Widget.Add(outObj); TempContext.Widget.Add(outObj);
TempContext.SaveChanges(); TempContext.SaveChanges();
@@ -142,9 +142,9 @@ namespace AyaNova.Biz
Widget outObj = new Widget(); Widget outObj = new Widget();
CopyObject.Copy(dbObj, outObj); CopyObject.Copy(dbObj, outObj);
outObj.Name = Util.StringUtil.NameUniquify(outObj.Name,255); outObj.Name = Util.StringUtil.NameUniquify(outObj.Name, 255);
outObj.Id=0; outObj.Id = 0;
outObj.ConcurrencyToken=0; outObj.ConcurrencyToken = 0;
//Test get serial id visible id number from generator //Test get serial id visible id number from generator
outObj.Serial = ServerBootConfig.WIDGET_SERIAL.GetNext(); outObj.Serial = ServerBootConfig.WIDGET_SERIAL.GetNext();
@@ -176,7 +176,7 @@ namespace AyaNova.Biz
CopyObject.Copy(inObj, dbObj, "Id,Serial"); CopyObject.Copy(inObj, dbObj, "Id,Serial");
dbObj.Tags = TagUtil.NormalizeTags(dbObj.Tags); dbObj.Tags = TagUtil.NormalizeTags(dbObj.Tags);
dbObj.CustomFields=JsonUtil.CompactJson(dbObj.CustomFields); dbObj.CustomFields = JsonUtil.CompactJson(dbObj.CustomFields);
//Set "original" value of concurrency token to input token //Set "original" value of concurrency token to input token
//this will allow EF to check it out //this will allow EF to check it out
@@ -210,7 +210,7 @@ namespace AyaNova.Biz
objectPatch.ApplyTo(dbObj); objectPatch.ApplyTo(dbObj);
dbObj.Tags = TagUtil.NormalizeTags(dbObj.Tags); dbObj.Tags = TagUtil.NormalizeTags(dbObj.Tags);
dbObj.CustomFields=JsonUtil.CompactJson(dbObj.CustomFields); dbObj.CustomFields = JsonUtil.CompactJson(dbObj.CustomFields);
ct.Entry(dbObj).OriginalValues["ConcurrencyToken"] = concurrencyToken; ct.Entry(dbObj).OriginalValues["ConcurrencyToken"] = concurrencyToken;
Validate(dbObj, SnapshotOfOriginalDBObj); Validate(dbObj, SnapshotOfOriginalDBObj);
@@ -233,7 +233,7 @@ namespace AyaNova.Biz
var SearchParams = new Search.SearchIndexProcessObjectParameters(UserLocaleId, obj.Id, BizType, obj.Name); var SearchParams = new Search.SearchIndexProcessObjectParameters(UserLocaleId, obj.Id, BizType, obj.Name);
SearchParams.AddText(obj.Notes).AddText(obj.Name).AddText(obj.Serial).AddText(obj.Tags).AddCustomFields(obj.CustomFields); SearchParams.AddText(obj.Notes).AddText(obj.Name).AddText(obj.Serial).AddText(obj.Tags).AddCustomFields(obj.CustomFields);
if (isNew) if (isNew)
Search.ProcessNewObjectKeywords(SearchParams); Search.ProcessNewObjectKeywords(SearchParams);
else else
@@ -322,16 +322,16 @@ namespace AyaNova.Biz
#pragma warning disable EF1000 #pragma warning disable EF1000
var items = await ct.Widget var items = await ct.Widget
.FromSqlRaw(q)
.AsNoTracking() .AsNoTracking()
.FromSql(q)
.Skip(pagingOptions.Offset.Value) .Skip(pagingOptions.Offset.Value)
.Take(pagingOptions.Limit.Value) .Take(pagingOptions.Limit.Value)
.ToArrayAsync(); .ToArrayAsync();
var totalRecordCount = await ct.Widget var totalRecordCount = await ct.Widget
.AsNoTracking() .FromSqlRaw(q)
.FromSql(q) .AsNoTracking()
.CountAsync(); .CountAsync();
#pragma warning restore EF1000 #pragma warning restore EF1000
var pageLinks = new PaginationLinkBuilder(Url, routeName, null, pagingOptions, totalRecordCount).PagingLinksObject(); var pageLinks = new PaginationLinkBuilder(Url, routeName, null, pagingOptions, totalRecordCount).PagingLinksObject();

View File

@@ -39,7 +39,8 @@ namespace AyaNova.Models
foreach (var entity in modelBuilder.Model.GetEntityTypes()) foreach (var entity in modelBuilder.Model.GetEntityTypes())
{ {
// Replace table names // Replace table names
entity.Relational().TableName = "a" + entity.Relational().TableName.ToLowerInvariant(); //entity.Relational().TableName = "a" + entity.Relational().TableName.ToLowerInvariant();
entity.SetTableName( "a" + entity.GetTableName().ToLowerInvariant());
// Replace column names // Replace column names
foreach (var property in entity.GetProperties()) foreach (var property in entity.GetProperties())
@@ -48,28 +49,34 @@ namespace AyaNova.Models
//set it up to work properly with PostgreSQL //set it up to work properly with PostgreSQL
if (property.Name == "ConcurrencyToken") if (property.Name == "ConcurrencyToken")
{ {
property.Relational().ColumnName = "xmin"; property.SetColumnName("xmin");
property.Relational().ColumnType = "xid"; property.SetColumnType("xid");
property.ValueGenerated = ValueGenerated.OnAddOrUpdate; // property.Relational().ColumnName = "xmin";
// property.Relational().ColumnType = "xid";
property.ValueGenerated = ValueGenerated.OnAddOrUpdate;
property.IsConcurrencyToken = true; property.IsConcurrencyToken = true;
} }
else else
property.Relational().ColumnName = property.Name.ToLowerInvariant(); property.SetColumnName(property.Name.ToLowerInvariant());
} }
foreach (var key in entity.GetKeys()) foreach (var key in entity.GetKeys())
{ {
key.Relational().Name = key.Relational().Name.ToLowerInvariant(); key.SetName(key.GetName().ToLowerInvariant());
// key.Relational().Name = key.Relational().Name.ToLowerInvariant();
} }
foreach (var key in entity.GetForeignKeys()) foreach (var key in entity.GetForeignKeys())
{ {
key.Relational().Name = key.Relational().Name.ToLowerInvariant(); //key.Relational().Name = key.Relational().Name.ToLowerInvariant();
key.SetConstraintName(key.GetConstraintName().ToLowerInvariant());
} }
foreach (var index in entity.GetIndexes()) foreach (var index in entity.GetIndexes())
{ {
index.Relational().Name = index.Relational().Name.ToLowerInvariant(); index.SetName(index.GetName().ToLowerInvariant());
//index.Relational().Name = index.Relational().Name.ToLowerInvariant();
} }
} }