增加codefirst迁移配置
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
5990477fdc
commit
ab68a63bdd
|
@ -1,107 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<SignAssembly>false</SignAssembly>
|
||||
<UserSecretsId>354572d4-9e15-4099-807c-63a2d29ff9f2</UserSecretsId>
|
||||
<LangVersion>default</LangVersion>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DocumentationFile>.\IRaCIS.Core.API.xml</DocumentationFile>
|
||||
<NoWarn>1701;1702;1591;</NoWarn>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DocumentationFile>bin\Release\IRaCIS.Core.API.xml</DocumentationFile>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<NoWarn>1701;1702;1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Controllers\ReviewerApi\**" />
|
||||
<Compile Remove="UploadFile\**" />
|
||||
<Content Remove="Controllers\ReviewerApi\**" />
|
||||
<Content Remove="UploadFile\**" />
|
||||
<EmbeddedResource Remove="Controllers\ReviewerApi\**" />
|
||||
<EmbeddedResource Remove="UploadFile\**" />
|
||||
<None Remove="Controllers\ReviewerApi\**" />
|
||||
<None Remove="UploadFile\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Remove="web.config" />
|
||||
<Content Remove="wwwroot\swagger\ui\abp.js" />
|
||||
<Content Remove="wwwroot\swagger\ui\abp.swagger.js" />
|
||||
<Content Remove="wwwroot\swagger\ui\Index.html" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove=".preview.jpg" />
|
||||
<None Remove="GrpcToken.proto" />
|
||||
<None Remove="IRaCIS.Core.API.xml" />
|
||||
<None Remove="Protos\GrpcToken.proto" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="GrpcToken.proto" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="wwwroot\swagger\ui\abp.js" />
|
||||
<EmbeddedResource Include="wwwroot\swagger\ui\abp.swagger.js" />
|
||||
<EmbeddedResource Include="wwwroot\swagger\ui\Index.html" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="Protos\GrpcToken.proto">
|
||||
<GrpcServices>Client</GrpcServices>
|
||||
</Protobuf>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AspNetCoreRateLimit" Version="4.0.1" />
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.2.0" />
|
||||
<PackageReference Include="EasyCaching.InMemory" Version="1.4.1" />
|
||||
<PackageReference Include="EasyCaching.Interceptor.Castle" Version="1.4.1" />
|
||||
<PackageReference Include="Google.Protobuf" Version="3.19.1" />
|
||||
<PackageReference Include="Grpc.Net.Client" Version="2.41.0" />
|
||||
<PackageReference Include="Grpc.Tools" Version="2.42.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Hangfire.Tags.SqlServer" Version="1.8.0" />
|
||||
<PackageReference Include="Invio.Extensions.Authentication.JwtBearer" Version="2.0.1" />
|
||||
<PackageReference Include="LogDashboard" Version="1.4.8" />
|
||||
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.14.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.1" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
|
||||
<PackageReference Include="Serilog.Enrichers.ClientInfo" Version="1.1.4" />
|
||||
<PackageReference Include="Serilog.Sinks.Email" Version="2.4.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\IRaCIS.Core.Application\IRaCIS.Core.Application.csproj" />
|
||||
<ProjectReference Include="..\IRaCIS.Core.Infra.EFCore\IRaCIS.Core.Infra.EFCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\PublishProfiles\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="NLog.config">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ProjectExtensions><VisualStudio><UserProperties anonymizetagsetting_1json__JsonSchema="http://json.schemastore.org/jovo-language-model" /></VisualStudio></ProjectExtensions>
|
||||
|
||||
|
||||
</Project>
|
|
@ -96,6 +96,12 @@
|
|||
<Folder Include="Properties\PublishProfiles\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="appsettings.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties properties_4launchsettings_1json__JsonSchema="" />
|
||||
|
|
|
@ -375,11 +375,6 @@
|
|||
<param name="memberSerialization">序列化成员</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:TimeZoneAdjustmentMiddleware">
|
||||
<summary>
|
||||
废弃,没用
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService">
|
||||
<summary>
|
||||
对称可逆加密
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// 废弃,没用
|
||||
/// </summary>
|
||||
public class TimeZoneAdjustmentMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
|
||||
public TimeZoneAdjustmentMiddleware(RequestDelegate next)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
if (string.IsNullOrEmpty(context.Request.ContentType))
|
||||
{
|
||||
// 请求没有内容体,可能是一个没有请求体的请求,比如 GET 请求
|
||||
await _next(context);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var timeZoneId = "Asia/Shanghai"; // 客户端默认时区
|
||||
|
||||
var timeZoneIdHeaderValue = context.Request.Headers["TimeZoneId"];
|
||||
|
||||
if (!string.IsNullOrEmpty(timeZoneIdHeaderValue))
|
||||
{
|
||||
timeZoneId = timeZoneIdHeaderValue;
|
||||
}
|
||||
|
||||
var timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
|
||||
|
||||
|
||||
|
||||
// 处理 JSON 请求体中的时间字段
|
||||
if (context.Request.ContentType.StartsWith("application/json"))
|
||||
{
|
||||
var requestBody = await new StreamReader(context.Request.Body).ReadToEndAsync();
|
||||
|
||||
// 使用 JSON.NET 或 System.Text.Json 解析 JSON 请求体
|
||||
// 假设请求体中有一个名为 "dateTime" 的时间字段
|
||||
dynamic jsonData = JsonConvert.DeserializeObject(requestBody);
|
||||
|
||||
if (jsonData.dateTime != null)
|
||||
{
|
||||
if (DateTime.TryParse((string)jsonData.dateTime, out DateTime dateTime))
|
||||
{
|
||||
// 将 JSON 请求体中的时间字段转换为服务器时区的时间
|
||||
var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone);
|
||||
jsonData.dateTime = serverTime;
|
||||
}
|
||||
}
|
||||
|
||||
// 将修改后的 JSON 请求体重新写入请求流中
|
||||
var jsonBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(jsonData));
|
||||
context.Request.Body = new MemoryStream(jsonBytes);
|
||||
context.Request.ContentLength = jsonBytes.Length;
|
||||
}
|
||||
|
||||
|
||||
// 处理 URL 表单参数
|
||||
var modifiedQuery = new Dictionary<string, StringValues>();
|
||||
|
||||
foreach (var key in context.Request.Query.Keys)
|
||||
{
|
||||
if (DateTime.TryParse(context.Request.Query[key], out DateTime dateTime))
|
||||
{
|
||||
// 将 URL 表单参数中的时间转换为服务器时区的时间
|
||||
var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone);
|
||||
modifiedQuery[key] = new StringValues(serverTime.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
modifiedQuery[key] = context.Request.Query[key];
|
||||
}
|
||||
}
|
||||
|
||||
context.Request.Query = new QueryCollection(modifiedQuery);
|
||||
|
||||
// 处理Form请求体中的参数
|
||||
if (context.Request.HasFormContentType)
|
||||
{
|
||||
var modifiedForm = new Dictionary<string, StringValues>();
|
||||
|
||||
foreach (var key in context.Request.Form.Keys)
|
||||
{
|
||||
if (DateTime.TryParse(context.Request.Form[key], out DateTime dateTime))
|
||||
{
|
||||
// 将请求体中的时间转换为服务器时区的时间
|
||||
var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone);
|
||||
modifiedForm[key] = new StringValues(serverTime.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
modifiedForm[key] = context.Request.Form[key];
|
||||
}
|
||||
}
|
||||
|
||||
var newFormCollection = new FormCollection(modifiedForm);
|
||||
|
||||
// 将新的表单集合设置回请求对象
|
||||
context.Request.Form = newFormCollection;
|
||||
}
|
||||
|
||||
await _next(context);
|
||||
}
|
||||
|
||||
}
|
|
@ -8,9 +8,11 @@ using Medallion.Threading;
|
|||
using Medallion.Threading.SqlServer;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace IRaCIS.Core.API
|
||||
|
@ -46,10 +48,11 @@ namespace IRaCIS.Core.API
|
|||
else
|
||||
{
|
||||
options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value, contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure());
|
||||
|
||||
}
|
||||
|
||||
|
||||
//迁移的时候,不生成外键
|
||||
options.ReplaceService<IMigrationsSqlGenerator, NoForeignKeyMigrationsSqlGenerator>();
|
||||
|
||||
|
||||
options.UseLoggerFactory(logFactory);
|
||||
|
|
|
@ -43,40 +43,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"easycaching": {
|
||||
"inmemory": {
|
||||
"MaxRdSecond": 120,
|
||||
"EnableLogging": false,
|
||||
"LockMs": 5000,
|
||||
"SleepMs": 300,
|
||||
"DBConfig": {
|
||||
"SizeLimit": 10000,
|
||||
"ExpirationScanFrequency": 60,
|
||||
"EnableReadDeepClone": true,
|
||||
"EnableWriteDeepClone": false
|
||||
}
|
||||
},
|
||||
"redis": {
|
||||
"MaxRdSecond": 120,
|
||||
"EnableLogging": false,
|
||||
"LockMs": 5000,
|
||||
"SleepMs": 300,
|
||||
"dbconfig": {
|
||||
"Password": "xc@123456",
|
||||
"IsSsl": false,
|
||||
"SslHost": null,
|
||||
"ConnectionTimeout": 5000,
|
||||
"AllowAdmin": true,
|
||||
"Endpoints": [
|
||||
{
|
||||
"Host": "47.117.164.182",
|
||||
"Port": 6379
|
||||
}
|
||||
],
|
||||
"Database": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"IRaCISImageStore": {
|
||||
"SwitchingMode": "RemainingDiskCapacity",
|
||||
"SwitchingRatio": 80,
|
||||
|
@ -93,7 +59,6 @@
|
|||
"DefaultPassword": "123456",
|
||||
"ImageShareExpireDays": 10
|
||||
},
|
||||
|
||||
"EncrypteResponseConfig": {
|
||||
"IsEnable": true,
|
||||
"ApiPathList": [
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
|
||||
|
||||
# 程序包管理控制台使用方式
|
||||
|
||||
1、生成迁移文件
|
||||
add-migration init -Context IRaCISDBContext
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 使用dotnet 命令迁移
|
||||
|
||||
# dotnet ef migrations add 本地迁移名字 -p 项目名 -c 数据库上下文名 -o 迁移文件生成目录
|
||||
|
||||
1、生成迁移文件
|
||||
dotnet ef migrations add Initial -s IRaCIS.Core.API -p IRaCIS.Core.Infra.EFCore -c IRaCISDBContext -o CodeFirst_MSSQL/Migrations
|
|
@ -0,0 +1,40 @@
|
|||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore;
|
||||
|
||||
|
||||
public class DecimalPrecisionConvention : IModelFinalizingConvention
|
||||
{
|
||||
private readonly int _precision;
|
||||
private readonly int _scale;
|
||||
|
||||
public DecimalPrecisionConvention(int precision, int scale)
|
||||
{
|
||||
_precision = precision;
|
||||
_scale = scale;
|
||||
}
|
||||
|
||||
public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext<IConventionModelBuilder> context)
|
||||
{
|
||||
|
||||
foreach (var property in modelBuilder.Metadata.GetEntityTypes()
|
||||
.SelectMany(
|
||||
entityType => entityType.GetDeclaredProperties()
|
||||
.Where(
|
||||
property => property.ClrType == typeof(decimal) || property.ClrType == typeof(decimal?))))
|
||||
{
|
||||
|
||||
|
||||
// 设置精度和小数位数
|
||||
property.SetPrecision(_precision);
|
||||
property.SetScale(_scale);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore;
|
||||
|
||||
/// <summary>
|
||||
/// Efcore 最新支持批量配置字符串类型长度作为保底的 官网参考:https://learn.microsoft.com/zh-cn/ef/core/modeling/bulk-configuration#conventions
|
||||
/// 设置不标注,默认长度,然后标注了与默认长度不一致,那么就是以标注的为准,同时如果标注了MaxLength ,对于mssql 那就是nvarcharMax,对于pgsql 就是text
|
||||
/// </summary>
|
||||
public class DefaultStringLengthConvention : IModelFinalizingConvention
|
||||
{
|
||||
private readonly int _defaultLenth;
|
||||
|
||||
public DefaultStringLengthConvention(int defaultLenth)
|
||||
{
|
||||
_defaultLenth = defaultLenth;
|
||||
}
|
||||
|
||||
public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext<IConventionModelBuilder> context)
|
||||
{
|
||||
foreach (var property in modelBuilder.Metadata.GetEntityTypes()
|
||||
.SelectMany(
|
||||
entityType => entityType.GetDeclaredProperties()
|
||||
.Where(
|
||||
property => property.ClrType == typeof(string))))
|
||||
{
|
||||
|
||||
// 获取 MaxLength 特性
|
||||
var maxLengthAttribute = property.PropertyInfo?.GetCustomAttributes(typeof(MaxLengthAttribute), false)
|
||||
.FirstOrDefault() as MaxLengthAttribute;
|
||||
|
||||
// 获取 StringLength 特性
|
||||
var stringLengthAttribute = property.PropertyInfo?.GetCustomAttributes(typeof(StringLengthAttribute), false)
|
||||
.FirstOrDefault() as StringLengthAttribute;
|
||||
|
||||
// 输出调试信息,看看是哪种特性生效
|
||||
if (stringLengthAttribute != null)
|
||||
{
|
||||
//Console.WriteLine($"{property.Name}: StringLength({stringLengthAttribute.MaximumLength})");
|
||||
property.Builder.HasMaxLength(stringLengthAttribute.MaximumLength);
|
||||
}
|
||||
else if (maxLengthAttribute != null)
|
||||
{
|
||||
//Console.WriteLine($"{property.Name}: MaxLength (no specific length, allowing max)");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Console.WriteLine($"{property.Name}: Default length 200");
|
||||
property.Builder.HasMaxLength(_defaultLenth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Migrations.Operations;
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 迁移的时候,忽略显示外键的建立,增加灵活性,同时为了兼容之前dbfirst 一个字段关联多个表
|
||||
/// </summary>
|
||||
public class NoForeignKeyMigrationsSqlGenerator : MigrationsSqlGenerator
|
||||
{
|
||||
public NoForeignKeyMigrationsSqlGenerator(
|
||||
MigrationsSqlGeneratorDependencies dependencies) : base(dependencies)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Generate(Microsoft.EntityFrameworkCore.Migrations.Operations.CreateTableOperation operation, IModel? model, MigrationCommandListBuilder builder, bool terminate = true)
|
||||
{
|
||||
operation.ForeignKeys.Clear();
|
||||
base.Generate(operation, model, builder, terminate);
|
||||
}
|
||||
}
|
|
@ -5,8 +5,8 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore
|
||||
{
|
||||
namespace IRaCIS.Core.Infra.EFCore;
|
||||
|
||||
public static class DbContextExt
|
||||
{
|
||||
|
||||
|
@ -247,4 +247,3 @@ namespace IRaCIS.Core.Infra.EFCore
|
|||
/// </summary>
|
||||
public List<ChangePropertyInfo> ChangeProperties { get; set; }
|
||||
}
|
||||
}
|
|
@ -25,8 +25,8 @@ using System.Collections.Generic;
|
|||
using System.ComponentModel;
|
||||
using Microsoft.VisualBasic;
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore
|
||||
{
|
||||
namespace IRaCIS.Core.Infra.EFCore;
|
||||
|
||||
#region 连接池废弃
|
||||
/// <summary>
|
||||
/// 报错,添加subject 报错,重复添加访视
|
||||
|
@ -60,7 +60,17 @@ namespace IRaCIS.Core.Infra.EFCore
|
|||
public IRaCISDBContext(DbContextOptions<IRaCISDBContext> options) : base(options)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// efcore codefirst 防止数据注解过多配置,全局统一配置
|
||||
/// </summary>
|
||||
/// <param name="configurationBuilder"></param>
|
||||
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
|
||||
{
|
||||
//decimal 不配置,默认精度是18,2
|
||||
configurationBuilder.Conventions.Add(_ => new DecimalPrecisionConvention(18,2));
|
||||
//针对字符串使用默认的长度配置为200,如果标注了StringLength 其他长度,就是标注的长度,如果标注了MaxLength 那么就是nvarcharMax
|
||||
configurationBuilder.Conventions.Add(_ => new DefaultStringLengthConvention(200));
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
|
@ -83,6 +93,7 @@ namespace IRaCIS.Core.Infra.EFCore
|
|||
//}
|
||||
#endregion
|
||||
|
||||
|
||||
//遍历实体模型手动配置
|
||||
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes().Where(q => q.GetInterface(typeof(IEntityTypeConfiguration<>).FullName) != null);
|
||||
foreach (var type in typesToRegister)
|
||||
|
@ -530,7 +541,4 @@ namespace IRaCIS.Core.Infra.EFCore
|
|||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using Microsoft.EntityFrameworkCore.Design;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore.Context;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Design-time DbContext Creation 用于迁移时指定使用哪个数据库
|
||||
/// </summary>
|
||||
public class IRaCISDBContextFactory : IDesignTimeDbContextFactory<IRaCISDBContext>
|
||||
{
|
||||
public IRaCISDBContext CreateDbContext(string[] args)
|
||||
{
|
||||
var optionsBuilder = new DbContextOptionsBuilder<IRaCISDBContext>();
|
||||
optionsBuilder.UseSqlServer("Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure());
|
||||
|
||||
return new IRaCISDBContext(optionsBuilder.Options);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,8 +4,8 @@ using MassTransit;
|
|||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
using Microsoft.EntityFrameworkCore.ValueGeneration;
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore
|
||||
{
|
||||
namespace IRaCIS.Core.Infra.EFCore;
|
||||
|
||||
public class MySequentialGuidValueGenerator : ValueGenerator<Guid>
|
||||
{
|
||||
public override Guid Next(EntityEntry entry)
|
||||
|
@ -14,5 +14,3 @@ namespace IRaCIS.Core.Infra.EFCore
|
|||
}
|
||||
public override bool GeneratesTemporaryValues => false;
|
||||
}
|
||||
|
||||
}
|
|
@ -25,6 +25,15 @@
|
|||
<PackageReference Include="EntityFrameworkCore.Exceptions.SqlServer" Version="8.1.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -11,6 +11,12 @@ namespace IRaCIS.Core.Test.CodeFirstTest.PGSQL.Migrations
|
|||
/// </summary>
|
||||
public class MaxStringLengthConvention : IModelFinalizingConvention
|
||||
{
|
||||
private readonly int _defaultLenth;
|
||||
|
||||
public MaxStringLengthConvention(int defaultLenth)
|
||||
{
|
||||
_defaultLenth = defaultLenth;
|
||||
}
|
||||
public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext<IConventionModelBuilder> context)
|
||||
{
|
||||
foreach (var property in modelBuilder.Metadata.GetEntityTypes()
|
||||
|
@ -31,17 +37,17 @@ namespace IRaCIS.Core.Test.CodeFirstTest.PGSQL.Migrations
|
|||
// 输出调试信息,看看是哪种特性生效
|
||||
if (stringLengthAttribute != null)
|
||||
{
|
||||
Console.WriteLine($"{property.Name}: StringLength({stringLengthAttribute.MaximumLength})");
|
||||
//Console.WriteLine($"{property.Name}: StringLength({stringLengthAttribute.MaximumLength})");
|
||||
property.Builder.HasMaxLength(stringLengthAttribute.MaximumLength);
|
||||
}
|
||||
else if (maxLengthAttribute != null)
|
||||
{
|
||||
Console.WriteLine($"{property.Name}: MaxLength (no specific length, allowing max)");
|
||||
//Console.WriteLine($"{property.Name}: MaxLength (no specific length, allowing max)");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"{property.Name}: Default length 200");
|
||||
property.Builder.HasMaxLength(200);
|
||||
//Console.WriteLine($"{property.Name}: Default length {_defaultLenth}");
|
||||
property.Builder.HasMaxLength(_defaultLenth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ public partial class PGContext : DbContext
|
|||
|
||||
//configurationBuilder.Conventions.Add(_ => new NoForeignKeyConvention());
|
||||
//针对字符串使用默认的长度配置
|
||||
configurationBuilder.Conventions.Add(_ => new MaxStringLengthConvention());
|
||||
configurationBuilder.Conventions.Add(_ => new MaxStringLengthConvention(200));
|
||||
}
|
||||
|
||||
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
|
||||
|
|
|
@ -52,16 +52,11 @@
|
|||
<PackageReference Include="Fluid.Core" Version="2.11.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="8.0.8" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
-c 指定数据库上下文名字
|
||||
-d 使用数据注解 不指定,默认是fluentAPI
|
||||
-t 指定要生成的表名
|
||||
-p 指定项目名字
|
||||
-p 指定项目名字 (包含上下文,并且产生迁移文件的项目)
|
||||
|
||||
备注: 因为是从数据库反向生成实体,所以会默认生成dbcontext ,每次生成想要的实体后,删除指定的名称context即可
|
||||
针对字符串类型,我们避免string字段 数据库存储null string? 数据库才存储null(除非有合理的理由),这样可以避免代码里面用string 变量,总是要判断是否为null
|
||||
|
|
Loading…
Reference in New Issue