ZeroDb 增加自定义异常,方便在外部捕获

This commit is contained in:
Tony Han 2024-06-23 16:19:06 +08:00
parent 6bf4c21af0
commit 07ee520a1f
6 changed files with 1447 additions and 1380 deletions

View File

@ -23,7 +23,7 @@
</PropertyGroup>
<ItemGroup>
<None Include="../../readme.md" Pack="true" PackagePath="\"/>
<None Include="../../readme.md" Pack="true" PackagePath="\" />
<None Include="../../logo.png" Pack="true" PackagePath="\" />
</ItemGroup>

View File

@ -0,0 +1,9 @@
using System;
namespace FreeSql.Extensions.ZeroEntity.Models
{
public class SchemaValidationException : Exception
{
public SchemaValidationException(string message) : base(message) { }
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace FreeSql.Extensions.ZeroEntity.Models
{
public class SchemaValidationResult
{
public readonly static SchemaValidationResult _schemaValidationResult = new SchemaValidationResult();
public static SchemaValidationResult SuccessedResult => _schemaValidationResult;
public SchemaValidationResult(string errorMessage)
{
ErrorMessage = errorMessage;
}
public string ErrorMessage { get; set; }
public bool Succeeded { get; set; } = false;
}
}

View File

@ -1,4 +1,5 @@
using FreeSql.DataAnnotations;
using FreeSql.Extensions.ZeroEntity.Models;
using FreeSql.Internal;
using FreeSql.Internal.CommonProvider;
using FreeSql.Internal.Model;
@ -64,23 +65,58 @@ ManyToMany 级联删除中间表(注意不删除外部根)
internal DbTransaction _transaction;
internal int _commandTimeout;
internal List<ZeroTableInfo> _tables;
public ZeroDbContext(IFreeSql orm, TableDescriptor[] schemas)
/// <summary>
/// 创建新的ZeroDbCotext实例
/// </summary>
/// <param name="orm">IfreeSql 对象</param>
/// <param name="schemas">动态表结构描述</param>
/// <param name="syncStructure">是否强制同步表结构</param>
/// <exception cref="SchemaValidationResult"> Schema 未验证通过时抛出验证异常</exception>
public ZeroDbContext(IFreeSql orm, TableDescriptor[] schemas, bool syncStructure = false)
{
_orm = orm;
_tables = ValidateSchemaToInfo(orm, schemas);
if (orm.CodeFirst.IsAutoSyncStructure)
_tables = ValidateSchemaToInfoInternal(orm, schemas);
if (syncStructure || orm.CodeFirst.IsAutoSyncStructure)
{
foreach (var table in _tables)
orm.CodeFirst.SyncStructure(table, table.DbName, false);
}
}
public SchemaValidationResult ValidateSchema(IEnumerable<TableDescriptor> schemas)
{
try
{
ValidateSchemaToInfoInternal(_orm, schemas);
}
catch (SchemaValidationException ex)
{
return new SchemaValidationResult(ex.Message);
}
return SchemaValidationResult.SuccessedResult;
}
public TableInfo GetTableInfo(string name) => _tables.Where(a => a.CsName == name).FirstOrDefault();
public void SyncStructure(string name)
public void SyncStructure()
{
foreach (var table in _tables)
_orm.CodeFirst.SyncStructure(table, table.DbName, false);
}
/// <summary>
/// 同步指定表结构
/// </summary>
/// <param name="name"></param>
public void SyncTableStructure(string name)
{
var table = GetTableInfo(name);
_orm.CodeFirst.SyncStructure(table, table.DbName, false);
}
static List<ZeroTableInfo> ValidateSchemaToInfo(IFreeSql orm, IEnumerable<TableDescriptor> schemas)
static List<ZeroTableInfo> ValidateSchemaToInfoInternal(IFreeSql orm, IEnumerable<TableDescriptor> schemas)
{
var common = (orm.Ado as AdoProvider)._util;
var tables = new List<ZeroTableInfo>();
@ -141,7 +177,8 @@ ManyToMany 级联删除中间表(注意不删除外部根)
nav.NavigateKey = dtdnav.Name;
nav.Table = tab;
nav.RefTable = tables.Where(a => a.CsName == dtdnav.RelTable).FirstOrDefault();
if (nav.RefTable == null) throw new Exception($"{error}未定义“{dtdnav.RelTable}”");
if (nav.RefTable == null) throw new SchemaValidationException($"{error}未定义“{dtdnav.RelTable}”");
switch (dtdnav.Type)
{
@ -173,22 +210,22 @@ ManyToMany 级联删除中间表(注意不删除外部根)
nav.RefType = TableRefType.ManyToMany;
var midtab = tables.Where(a => a.CsName == dtdnav.ManyToMany).FirstOrDefault();
nav.RefMiddleTable = midtab;
if (nav.RefMiddleTable == null) throw new Exception($"{error}ManyToMany未定义“{dtdnav.ManyToMany}”");
if (nav.RefMiddleTable == null) throw new SchemaValidationException($"{error}ManyToMany未定义“{dtdnav.ManyToMany}”");
var midtabRaw = schemas.Where(a => a.Name == midtab.CsName).FirstOrDefault();
var midTabNav1 = midtabRaw.Navigates.Where(a => a.Type == TableDescriptor.NavigateType.ManyToOne && a.RelTable == nav.Table.CsName).FirstOrDefault();
if (midTabNav1 == null) throw new Exception($"{error}ManyToMany中间表“{dtdnav.ManyToMany}”没有与表“{nav.Table.CsName}”形成 ManyToOne 关联");
if (midTabNav1 == null) throw new SchemaValidationException($"{error}ManyToMany中间表“{dtdnav.ManyToMany}”没有与表“{nav.Table.CsName}”形成 ManyToOne 关联");
var midTabNav1Columns = midTabNav1.Bind.Split(',')
.Select(a => midtab.ColumnsByCs.TryGetValue(a.Trim(), out var refcol) ? refcol.CsName : "")
.Where(a => string.IsNullOrWhiteSpace(a) == false).ToArray();
var midTabNav2 = midtabRaw.Navigates.Where(a => a.Type == TableDescriptor.NavigateType.ManyToOne && a.RelTable == nav.RefTable.CsName).FirstOrDefault();
if (midTabNav2 == null) throw new Exception($"{error}ManyToMany中间表“{dtdnav.ManyToMany}”没有与表“{nav.RefTable.CsName}”形成 ManyToOne 关联");
if (midTabNav2 == null) throw new SchemaValidationException($"{error}ManyToMany中间表“{dtdnav.ManyToMany}”没有与表“{nav.RefTable.CsName}”形成 ManyToOne 关联");
var midTabNav2Columns = midTabNav2.Bind.Split(',')
.Select(a => midtab.ColumnsByCs.TryGetValue(a.Trim(), out var refcol) ? refcol.CsName : "")
.Where(a => string.IsNullOrWhiteSpace(a) == false).ToArray();
if (midTabNav1Columns.Length != nav.Table.Primarys.Length) throw new Exception($"{error}ManyToMany中间表“{dtdnav.ManyToMany}”关联字段的数目不相等");
if (midTabNav1Columns.Where((a, idx) => midtab.ColumnsByCs[a].CsType != nav.Table.Primarys[idx].CsType).Any()) throw new Exception($"{error}ManyToMany中间表“{dtdnav.ManyToMany}”关联字段的类型不相等");
if (midTabNav2Columns.Length != nav.RefTable.Primarys.Length) throw new Exception($"{error}ManyToMany中间表“{dtdnav.ManyToMany}”与表“{nav.RefTable.CsName}”关联字段的数目不相等");
if (midTabNav2Columns.Where((a, idx) => midtab.ColumnsByCs[a].CsType != nav.RefTable.Primarys[idx].CsType).Any()) throw new Exception($"{error}ManyToMany中间表“{dtdnav.ManyToMany}”与表“{nav.RefTable.CsName}”关联字段的类型不相等");
if (midTabNav1Columns.Length != nav.Table.Primarys.Length) throw new SchemaValidationException($"{error}ManyToMany中间表“{dtdnav.ManyToMany}”关联字段的数目不相等");
if (midTabNav1Columns.Where((a, idx) => midtab.ColumnsByCs[a].CsType != nav.Table.Primarys[idx].CsType).Any()) throw new SchemaValidationException($"{error}ManyToMany中间表“{dtdnav.ManyToMany}”关联字段的类型不相等");
if (midTabNav2Columns.Length != nav.RefTable.Primarys.Length) throw new SchemaValidationException($"{error}ManyToMany中间表“{dtdnav.ManyToMany}”与表“{nav.RefTable.CsName}”关联字段的数目不相等");
if (midTabNav2Columns.Where((a, idx) => midtab.ColumnsByCs[a].CsType != nav.RefTable.Primarys[idx].CsType).Any()) throw new SchemaValidationException($"{error}ManyToMany中间表“{dtdnav.ManyToMany}”与表“{nav.RefTable.CsName}”关联字段的类型不相等");
nav.Columns.AddRange(nav.Table.Primarys.Select(a => a.CsName));
nav.MiddleColumns.AddRange(midTabNav1Columns);
nav.MiddleColumns.AddRange(midTabNav2Columns);
@ -200,8 +237,8 @@ ManyToMany 级联删除中间表(注意不删除外部根)
case TableDescriptor.NavigateType.OneToOne:
case TableDescriptor.NavigateType.ManyToOne:
case TableDescriptor.NavigateType.OneToMany:
if (nav.Columns.Any() == false || nav.Columns.Count != nav.RefColumns.Count) throw new Exception($"{error}与表“{dtdnav.RelTable}”关联字段的数目不相等");
if (nav.Columns.Where((a, idx) => nav.Table.ColumnsByCs[a].CsType != nav.RefTable.ColumnsByCs[nav.RefColumns[idx]].CsType).Any()) throw new Exception($"{error}与表“{dtdnav.RelTable}”关联字段的类型不匹配");
if (nav.Columns.Any() == false || nav.Columns.Count != nav.RefColumns.Count) throw new SchemaValidationException($"{error}与表“{dtdnav.RelTable}”关联字段的数目不相等");
if (nav.Columns.Where((a, idx) => nav.Table.ColumnsByCs[a].CsType != nav.RefTable.ColumnsByCs[nav.RefColumns[idx]].CsType).Any()) throw new SchemaValidationException($"{error}与表“{dtdnav.RelTable}”关联字段的类型不匹配");
break;
}
tab.Navigates.Add(dtdnav.Name, nav);

View File

@ -217,7 +217,7 @@ homejun,
## 💕 Donation
L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元、兰州天擎赵 500元、哈利路亚 300元、
L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、Nothing 100元、兰州天擎赵 500元、哈利路亚 300元、
无名 100元、蛰伏 99.99元、TCYM 66.66元、MOTA 5元、LDZXG 30元、Near 30元、建爽 66元、无名 200元、LambertWu 100元、无名 18.88元、乌龙 50元、无名 100元、陳怼怼 66.66元、陳怼怼 66.66元、丁淮 100元、李伟坚-Excel催化剂 100元、白狐 6.66元、她微笑的脸y 30元、Eternity²º²¹ 588元、夜归柴门 88元、蔡易喋 666.66元、
*礼 10元、litrpa 88元、Alax CHOW 200元、Daily 66元、k\*t 66元、蓝 100元、*菜 10元、生命如歌 1000元、山鸡 88元、平凡 100元、大树 1000元、软软的毛毛虫 66.66元、问卷星 2000元、与你无关 5000元

View File

@ -218,7 +218,7 @@ homejun,
## 💕 Donation (捐赠)
L\*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元、兰州天擎赵 500元、哈利路亚 300元、
L\*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、Nothing 100元、兰州天擎赵 500元、哈利路亚 300元、
无名 100元、蛰伏 99.99元、TCYM 66.66元、MOTA 5元、LDZXG 30元、Near 30元、建爽 66元、无名 200元、LambertWu 100元、无名 18.88元、乌龙 50元、无名 100元、陳怼怼 66.66元、陳怼怼 66.66元、丁淮 100元、李伟坚-Excel催化剂 100元、白狐 6.66元、她微笑的脸y 30元、Eternity²º²¹ 588元、夜归柴门 88元、蔡易喋 666.66元、
*礼 10元、litrpa 88元、Alax CHOW 200元、Daily 66元、k*t 66元、蓝 100元、\*菜 10元、生命如歌 1000元、山鸡 88元、平凡 100元、大树 1000元、软软的毛毛虫 66.66元、问卷星 2000元、与你无关 5000元