增加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\" />
|
<Folder Include="Properties\PublishProfiles\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Update="appsettings.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<VisualStudio>
|
<VisualStudio>
|
||||||
<UserProperties properties_4launchsettings_1json__JsonSchema="" />
|
<UserProperties properties_4launchsettings_1json__JsonSchema="" />
|
||||||
|
|
|
@ -375,11 +375,6 @@
|
||||||
<param name="memberSerialization">序列化成员</param>
|
<param name="memberSerialization">序列化成员</param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="T:TimeZoneAdjustmentMiddleware">
|
|
||||||
<summary>
|
|
||||||
废弃,没用
|
|
||||||
</summary>
|
|
||||||
</member>
|
|
||||||
<member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService">
|
<member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService">
|
||||||
<summary>
|
<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 Medallion.Threading.SqlServer;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
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.Extensions.Options;
|
||||||
using StackExchange.Redis;
|
using StackExchange.Redis;
|
||||||
|
|
||||||
namespace IRaCIS.Core.API
|
namespace IRaCIS.Core.API
|
||||||
|
@ -46,10 +48,11 @@ namespace IRaCIS.Core.API
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value, contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure());
|
options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value, contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//迁移的时候,不生成外键
|
||||||
|
options.ReplaceService<IMigrationsSqlGenerator, NoForeignKeyMigrationsSqlGenerator>();
|
||||||
|
|
||||||
|
|
||||||
options.UseLoggerFactory(logFactory);
|
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": {
|
"IRaCISImageStore": {
|
||||||
"SwitchingMode": "RemainingDiskCapacity",
|
"SwitchingMode": "RemainingDiskCapacity",
|
||||||
"SwitchingRatio": 80,
|
"SwitchingRatio": 80,
|
||||||
|
@ -93,7 +59,6 @@
|
||||||
"DefaultPassword": "123456",
|
"DefaultPassword": "123456",
|
||||||
"ImageShareExpireDays": 10
|
"ImageShareExpireDays": 10
|
||||||
},
|
},
|
||||||
|
|
||||||
"EncrypteResponseConfig": {
|
"EncrypteResponseConfig": {
|
||||||
"IsEnable": true,
|
"IsEnable": true,
|
||||||
"ApiPathList": [
|
"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,246 +5,245 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Infra.EFCore
|
namespace IRaCIS.Core.Infra.EFCore;
|
||||||
|
|
||||||
|
public static class DbContextExt
|
||||||
{
|
{
|
||||||
public static class DbContextExt
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取变化的实体信息
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="db"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IEnumerable<ChangeEntry> GetChanges<T>(this DbContext db)
|
||||||
{
|
{
|
||||||
|
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Modified && e.Entity is T).Select(e =>
|
||||||
/// <summary>
|
|
||||||
/// 获取变化的实体信息
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <param name="db"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static IEnumerable<ChangeEntry> GetChanges<T>(this DbContext db)
|
|
||||||
{
|
{
|
||||||
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Modified && e.Entity is T).Select(e =>
|
var originalObject = e.OriginalValues.ToObject();
|
||||||
|
var currentObject = e.CurrentValues.ToObject();
|
||||||
|
return new ChangeEntry
|
||||||
{
|
{
|
||||||
var originalObject = e.OriginalValues.ToObject();
|
EntityState = e.State,
|
||||||
var currentObject = e.CurrentValues.ToObject();
|
Entity = e.Entity,
|
||||||
return new ChangeEntry
|
EntityType = e.OriginalValues.EntityType.ClrType,
|
||||||
|
ChangeProperties = e.OriginalValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(originalObject))).Zip(e.CurrentValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(currentObject))), (t1, t2) => new ChangePropertyInfo()
|
||||||
{
|
{
|
||||||
EntityState = e.State,
|
PropertyInfo = t1.Property.PropertyInfo,
|
||||||
Entity = e.Entity,
|
OriginalValue = t1.Value,
|
||||||
EntityType = e.OriginalValues.EntityType.ClrType,
|
CurrentValue = t2.Value,
|
||||||
ChangeProperties = e.OriginalValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(originalObject))).Zip(e.CurrentValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(currentObject))), (t1, t2) => new ChangePropertyInfo()
|
IsPrimaryKey = t1.Property.IsPrimaryKey(),
|
||||||
{
|
IsForeignKey = t1.Property.IsForeignKey()
|
||||||
PropertyInfo = t1.Property.PropertyInfo,
|
}).Where(t => Comparer.Default.Compare(t.OriginalValue, t.CurrentValue) != 0).ToList()
|
||||||
OriginalValue = t1.Value,
|
};
|
||||||
CurrentValue = t2.Value,
|
});
|
||||||
IsPrimaryKey = t1.Property.IsPrimaryKey(),
|
|
||||||
IsForeignKey = t1.Property.IsForeignKey()
|
|
||||||
}).Where(t => Comparer.Default.Compare(t.OriginalValue, t.CurrentValue) != 0).ToList()
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取变化的实体信息
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="db"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static IEnumerable<ChangeEntry> GetChanges(this DbContext db)
|
|
||||||
{
|
|
||||||
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Modified).Select(e =>
|
|
||||||
{
|
|
||||||
var originalObject = e.OriginalValues.ToObject();
|
|
||||||
var currentObject = e.CurrentValues.ToObject();
|
|
||||||
return new ChangeEntry()
|
|
||||||
{
|
|
||||||
EntityState = e.State,
|
|
||||||
Entity = e.Entity,
|
|
||||||
EntityType = e.OriginalValues.EntityType.ClrType,
|
|
||||||
ChangeProperties = e.OriginalValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(originalObject))).Zip(e.CurrentValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(currentObject))), (t1, t2) => new ChangePropertyInfo()
|
|
||||||
{
|
|
||||||
PropertyInfo = t1.Property.PropertyInfo,
|
|
||||||
OriginalValue = t1.Value,
|
|
||||||
CurrentValue = t2.Value,
|
|
||||||
IsPrimaryKey = t1.Property.IsPrimaryKey(),
|
|
||||||
IsForeignKey = t1.Property.IsForeignKey(),
|
|
||||||
}).Where(t => Comparer.Default.Compare(t.OriginalValue, t.CurrentValue) != 0).ToList()
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取添加的实体信息
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <param name="db"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static IEnumerable<ChangeEntry> GetAdded<T>(this DbContext db)
|
|
||||||
{
|
|
||||||
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Added && e.Entity is T).Select(e =>
|
|
||||||
{
|
|
||||||
var currentObject = e.CurrentValues.ToObject();
|
|
||||||
return new ChangeEntry
|
|
||||||
{
|
|
||||||
EntityState = e.State,
|
|
||||||
Entity = e.Entity,
|
|
||||||
EntityType = e.CurrentValues.EntityType.ClrType,
|
|
||||||
ChangeProperties = e.CurrentValues.Properties.Select(p => new ChangePropertyInfo()
|
|
||||||
{
|
|
||||||
PropertyInfo = p.PropertyInfo,
|
|
||||||
CurrentValue = p.PropertyInfo.GetValue(currentObject),
|
|
||||||
IsPrimaryKey = p.IsPrimaryKey(),
|
|
||||||
IsForeignKey = p.IsForeignKey(),
|
|
||||||
}).ToList()
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取添加的实体信息
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="db"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static IEnumerable<ChangeEntry> GetAdded(this DbContext db)
|
|
||||||
{
|
|
||||||
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Added).Select(e =>
|
|
||||||
{
|
|
||||||
var currentObject = e.CurrentValues.ToObject();
|
|
||||||
return new ChangeEntry
|
|
||||||
{
|
|
||||||
EntityState = e.State,
|
|
||||||
Entity = e.Entity,
|
|
||||||
EntityType = e.CurrentValues.EntityType.ClrType,
|
|
||||||
ChangeProperties = e.CurrentValues.Properties.Select(p => new ChangePropertyInfo()
|
|
||||||
{
|
|
||||||
PropertyInfo = p.PropertyInfo,
|
|
||||||
CurrentValue = p.PropertyInfo.GetValue(currentObject),
|
|
||||||
IsPrimaryKey = p.IsPrimaryKey(),
|
|
||||||
IsForeignKey = p.IsForeignKey(),
|
|
||||||
}).ToList()
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取移除的实体信息
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <param name="db"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static IEnumerable<ChangeEntry> GetRemoved<T>(this DbContext db)
|
|
||||||
{
|
|
||||||
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted && e.Entity is T).Select(e =>
|
|
||||||
{
|
|
||||||
var originalObject = e.OriginalValues.ToObject();
|
|
||||||
return new ChangeEntry
|
|
||||||
{
|
|
||||||
EntityState = e.State,
|
|
||||||
Entity = e.Entity,
|
|
||||||
EntityType = e.OriginalValues.EntityType.ClrType,
|
|
||||||
ChangeProperties = e.OriginalValues.Properties.Select(p => new ChangePropertyInfo()
|
|
||||||
{
|
|
||||||
PropertyInfo = p.PropertyInfo,
|
|
||||||
OriginalValue = p.PropertyInfo.GetValue(originalObject),
|
|
||||||
IsPrimaryKey = p.IsPrimaryKey(),
|
|
||||||
IsForeignKey = p.IsForeignKey(),
|
|
||||||
}).ToList()
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取移除的实体信息
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="db"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static IEnumerable<ChangeEntry> GetRemoved(this DbContext db)
|
|
||||||
{
|
|
||||||
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted).Select(e =>
|
|
||||||
{
|
|
||||||
var originalObject = e.OriginalValues.ToObject();
|
|
||||||
return new ChangeEntry
|
|
||||||
{
|
|
||||||
EntityState = e.State,
|
|
||||||
Entity = e.Entity,
|
|
||||||
EntityType = e.OriginalValues.EntityType.ClrType,
|
|
||||||
ChangeProperties = e.OriginalValues.Properties.Select(p => new ChangePropertyInfo()
|
|
||||||
{
|
|
||||||
PropertyInfo = p.PropertyInfo,
|
|
||||||
OriginalValue = p.PropertyInfo.GetValue(originalObject),
|
|
||||||
IsPrimaryKey = p.IsPrimaryKey(),
|
|
||||||
IsForeignKey = p.IsForeignKey(),
|
|
||||||
}).ToList()
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取所有的变更信息
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <param name="db"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static IEnumerable<ChangeEntry> GetAllChanges<T>(this DbContext db)
|
|
||||||
{
|
|
||||||
return GetChanges<T>(db).Union(GetAdded<T>(db)).Union(GetRemoved<T>(db));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取所有的变更信息
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="db"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static IEnumerable<ChangeEntry> GetAllChanges(this DbContext db)
|
|
||||||
{
|
|
||||||
return GetChanges(db).Union(GetAdded(db)).Union(GetRemoved(db));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ChangePropertyInfo
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取变化的实体信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="db"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IEnumerable<ChangeEntry> GetChanges(this DbContext db)
|
||||||
{
|
{
|
||||||
/// <summary>
|
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Modified).Select(e =>
|
||||||
/// 属性
|
{
|
||||||
/// </summary>
|
var originalObject = e.OriginalValues.ToObject();
|
||||||
public PropertyInfo PropertyInfo { get; set; }
|
var currentObject = e.CurrentValues.ToObject();
|
||||||
|
return new ChangeEntry()
|
||||||
/// <summary>
|
{
|
||||||
/// 原始值
|
EntityState = e.State,
|
||||||
/// </summary>
|
Entity = e.Entity,
|
||||||
public object OriginalValue { get; set; }
|
EntityType = e.OriginalValues.EntityType.ClrType,
|
||||||
|
ChangeProperties = e.OriginalValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(originalObject))).Zip(e.CurrentValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(currentObject))), (t1, t2) => new ChangePropertyInfo()
|
||||||
/// <summary>
|
{
|
||||||
/// 新值
|
PropertyInfo = t1.Property.PropertyInfo,
|
||||||
/// </summary>
|
OriginalValue = t1.Value,
|
||||||
public object CurrentValue { get; set; }
|
CurrentValue = t2.Value,
|
||||||
|
IsPrimaryKey = t1.Property.IsPrimaryKey(),
|
||||||
/// <summary>
|
IsForeignKey = t1.Property.IsForeignKey(),
|
||||||
/// 是否是主键
|
}).Where(t => Comparer.Default.Compare(t.OriginalValue, t.CurrentValue) != 0).ToList()
|
||||||
/// </summary>
|
};
|
||||||
public bool IsPrimaryKey { get; set; }
|
});
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否是外键
|
|
||||||
/// </summary>
|
|
||||||
public bool IsForeignKey { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ChangeEntry
|
/// <summary>
|
||||||
|
/// 获取添加的实体信息
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="db"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IEnumerable<ChangeEntry> GetAdded<T>(this DbContext db)
|
||||||
{
|
{
|
||||||
/// <summary>
|
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Added && e.Entity is T).Select(e =>
|
||||||
/// 所属实体
|
{
|
||||||
/// </summary>
|
var currentObject = e.CurrentValues.ToObject();
|
||||||
public object Entity { get; set; }
|
return new ChangeEntry
|
||||||
|
{
|
||||||
/// <summary>
|
EntityState = e.State,
|
||||||
/// 实体类型
|
Entity = e.Entity,
|
||||||
/// </summary>
|
EntityType = e.CurrentValues.EntityType.ClrType,
|
||||||
public Type EntityType { get; set; }
|
ChangeProperties = e.CurrentValues.Properties.Select(p => new ChangePropertyInfo()
|
||||||
|
{
|
||||||
/// <summary>
|
PropertyInfo = p.PropertyInfo,
|
||||||
/// 变更类型
|
CurrentValue = p.PropertyInfo.GetValue(currentObject),
|
||||||
/// </summary>
|
IsPrimaryKey = p.IsPrimaryKey(),
|
||||||
public EntityState EntityState { get; set; }
|
IsForeignKey = p.IsForeignKey(),
|
||||||
|
}).ToList()
|
||||||
/// <summary>
|
};
|
||||||
/// 字段变更信息
|
});
|
||||||
/// </summary>
|
|
||||||
public List<ChangePropertyInfo> ChangeProperties { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取添加的实体信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="db"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IEnumerable<ChangeEntry> GetAdded(this DbContext db)
|
||||||
|
{
|
||||||
|
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Added).Select(e =>
|
||||||
|
{
|
||||||
|
var currentObject = e.CurrentValues.ToObject();
|
||||||
|
return new ChangeEntry
|
||||||
|
{
|
||||||
|
EntityState = e.State,
|
||||||
|
Entity = e.Entity,
|
||||||
|
EntityType = e.CurrentValues.EntityType.ClrType,
|
||||||
|
ChangeProperties = e.CurrentValues.Properties.Select(p => new ChangePropertyInfo()
|
||||||
|
{
|
||||||
|
PropertyInfo = p.PropertyInfo,
|
||||||
|
CurrentValue = p.PropertyInfo.GetValue(currentObject),
|
||||||
|
IsPrimaryKey = p.IsPrimaryKey(),
|
||||||
|
IsForeignKey = p.IsForeignKey(),
|
||||||
|
}).ToList()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取移除的实体信息
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="db"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IEnumerable<ChangeEntry> GetRemoved<T>(this DbContext db)
|
||||||
|
{
|
||||||
|
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted && e.Entity is T).Select(e =>
|
||||||
|
{
|
||||||
|
var originalObject = e.OriginalValues.ToObject();
|
||||||
|
return new ChangeEntry
|
||||||
|
{
|
||||||
|
EntityState = e.State,
|
||||||
|
Entity = e.Entity,
|
||||||
|
EntityType = e.OriginalValues.EntityType.ClrType,
|
||||||
|
ChangeProperties = e.OriginalValues.Properties.Select(p => new ChangePropertyInfo()
|
||||||
|
{
|
||||||
|
PropertyInfo = p.PropertyInfo,
|
||||||
|
OriginalValue = p.PropertyInfo.GetValue(originalObject),
|
||||||
|
IsPrimaryKey = p.IsPrimaryKey(),
|
||||||
|
IsForeignKey = p.IsForeignKey(),
|
||||||
|
}).ToList()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取移除的实体信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="db"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IEnumerable<ChangeEntry> GetRemoved(this DbContext db)
|
||||||
|
{
|
||||||
|
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted).Select(e =>
|
||||||
|
{
|
||||||
|
var originalObject = e.OriginalValues.ToObject();
|
||||||
|
return new ChangeEntry
|
||||||
|
{
|
||||||
|
EntityState = e.State,
|
||||||
|
Entity = e.Entity,
|
||||||
|
EntityType = e.OriginalValues.EntityType.ClrType,
|
||||||
|
ChangeProperties = e.OriginalValues.Properties.Select(p => new ChangePropertyInfo()
|
||||||
|
{
|
||||||
|
PropertyInfo = p.PropertyInfo,
|
||||||
|
OriginalValue = p.PropertyInfo.GetValue(originalObject),
|
||||||
|
IsPrimaryKey = p.IsPrimaryKey(),
|
||||||
|
IsForeignKey = p.IsForeignKey(),
|
||||||
|
}).ToList()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有的变更信息
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="db"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IEnumerable<ChangeEntry> GetAllChanges<T>(this DbContext db)
|
||||||
|
{
|
||||||
|
return GetChanges<T>(db).Union(GetAdded<T>(db)).Union(GetRemoved<T>(db));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有的变更信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="db"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IEnumerable<ChangeEntry> GetAllChanges(this DbContext db)
|
||||||
|
{
|
||||||
|
return GetChanges(db).Union(GetAdded(db)).Union(GetRemoved(db));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ChangePropertyInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 属性
|
||||||
|
/// </summary>
|
||||||
|
public PropertyInfo PropertyInfo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 原始值
|
||||||
|
/// </summary>
|
||||||
|
public object OriginalValue { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新值
|
||||||
|
/// </summary>
|
||||||
|
public object CurrentValue { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否是主键
|
||||||
|
/// </summary>
|
||||||
|
public bool IsPrimaryKey { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否是外键
|
||||||
|
/// </summary>
|
||||||
|
public bool IsForeignKey { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ChangeEntry
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 所属实体
|
||||||
|
/// </summary>
|
||||||
|
public object Entity { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 实体类型
|
||||||
|
/// </summary>
|
||||||
|
public Type EntityType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 变更类型
|
||||||
|
/// </summary>
|
||||||
|
public EntityState EntityState { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 字段变更信息
|
||||||
|
/// </summary>
|
||||||
|
public List<ChangePropertyInfo> ChangeProperties { get; set; }
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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,15 +4,13 @@ using MassTransit;
|
||||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||||
using Microsoft.EntityFrameworkCore.ValueGeneration;
|
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)
|
|
||||||
{
|
|
||||||
return NewId.NextSequentialGuid();
|
|
||||||
}
|
|
||||||
public override bool GeneratesTemporaryValues => false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public class MySequentialGuidValueGenerator : ValueGenerator<Guid>
|
||||||
|
{
|
||||||
|
public override Guid Next(EntityEntry entry)
|
||||||
|
{
|
||||||
|
return NewId.NextSequentialGuid();
|
||||||
|
}
|
||||||
|
public override bool GeneratesTemporaryValues => false;
|
||||||
}
|
}
|
|
@ -25,6 +25,15 @@
|
||||||
<PackageReference Include="EntityFrameworkCore.Exceptions.SqlServer" Version="8.1.3" />
|
<PackageReference Include="EntityFrameworkCore.Exceptions.SqlServer" Version="8.1.3" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.8" />
|
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.8" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
|
<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>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -20,7 +20,7 @@ https://www.cnblogs.com/cqpanda/p/16815263.html
|
||||||
5、撤销某次更新到数据库的迁移(自动执行down 方法)
|
5、撤销某次更新到数据库的迁移(自动执行down 方法)
|
||||||
dotnet ef database update 某次迁移的前一次迁移名称 -p IRaCIS.Core.Test -c IRCContext
|
dotnet ef database update 某次迁移的前一次迁移名称 -p IRaCIS.Core.Test -c IRCContext
|
||||||
|
|
||||||
dotnet ef migrations add RemoveForeignKey -p IRaCIS.Core.Test -c IRCContext -o CodeFirstTest/MSSQL/Migrations
|
dotnet ef migrations add RemoveForeignKey -p IRaCIS.Core.Test -c IRCContext -o CodeFirstTest/MSSQL/Migrations
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,12 @@ namespace IRaCIS.Core.Test.CodeFirstTest.PGSQL.Migrations
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MaxStringLengthConvention : IModelFinalizingConvention
|
public class MaxStringLengthConvention : IModelFinalizingConvention
|
||||||
{
|
{
|
||||||
|
private readonly int _defaultLenth;
|
||||||
|
|
||||||
|
public MaxStringLengthConvention(int defaultLenth)
|
||||||
|
{
|
||||||
|
_defaultLenth = defaultLenth;
|
||||||
|
}
|
||||||
public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext<IConventionModelBuilder> context)
|
public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext<IConventionModelBuilder> context)
|
||||||
{
|
{
|
||||||
foreach (var property in modelBuilder.Metadata.GetEntityTypes()
|
foreach (var property in modelBuilder.Metadata.GetEntityTypes()
|
||||||
|
@ -31,17 +37,17 @@ namespace IRaCIS.Core.Test.CodeFirstTest.PGSQL.Migrations
|
||||||
// 输出调试信息,看看是哪种特性生效
|
// 输出调试信息,看看是哪种特性生效
|
||||||
if (stringLengthAttribute != null)
|
if (stringLengthAttribute != null)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{property.Name}: StringLength({stringLengthAttribute.MaximumLength})");
|
//Console.WriteLine($"{property.Name}: StringLength({stringLengthAttribute.MaximumLength})");
|
||||||
property.Builder.HasMaxLength(stringLengthAttribute.MaximumLength);
|
property.Builder.HasMaxLength(stringLengthAttribute.MaximumLength);
|
||||||
}
|
}
|
||||||
else if (maxLengthAttribute != null)
|
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
|
else
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{property.Name}: Default length 200");
|
//Console.WriteLine($"{property.Name}: Default length {_defaultLenth}");
|
||||||
property.Builder.HasMaxLength(200);
|
property.Builder.HasMaxLength(_defaultLenth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ public partial class PGContext : DbContext
|
||||||
|
|
||||||
//configurationBuilder.Conventions.Add(_ => new NoForeignKeyConvention());
|
//configurationBuilder.Conventions.Add(_ => new NoForeignKeyConvention());
|
||||||
//针对字符串使用默认的长度配置
|
//针对字符串使用默认的长度配置
|
||||||
configurationBuilder.Conventions.Add(_ => new MaxStringLengthConvention());
|
configurationBuilder.Conventions.Add(_ => new MaxStringLengthConvention(200));
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
|
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
|
||||||
|
|
|
@ -52,16 +52,11 @@
|
||||||
<PackageReference Include="Fluid.Core" Version="2.11.1" />
|
<PackageReference Include="Fluid.Core" Version="2.11.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" 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">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.8">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</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>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
-c 指定数据库上下文名字
|
-c 指定数据库上下文名字
|
||||||
-d 使用数据注解 不指定,默认是fluentAPI
|
-d 使用数据注解 不指定,默认是fluentAPI
|
||||||
-t 指定要生成的表名
|
-t 指定要生成的表名
|
||||||
-p 指定项目名字
|
-p 指定项目名字 (包含上下文,并且产生迁移文件的项目)
|
||||||
|
|
||||||
备注: 因为是从数据库反向生成实体,所以会默认生成dbcontext ,每次生成想要的实体后,删除指定的名称context即可
|
备注: 因为是从数据库反向生成实体,所以会默认生成dbcontext ,每次生成想要的实体后,删除指定的名称context即可
|
||||||
针对字符串类型,我们避免string字段 数据库存储null string? 数据库才存储null(除非有合理的理由),这样可以避免代码里面用string 变量,总是要判断是否为null
|
针对字符串类型,我们避免string字段 数据库存储null string? 数据库才存储null(除非有合理的理由),这样可以避免代码里面用string 变量,总是要判断是否为null
|
||||||
|
|
Loading…
Reference in New Issue