diff --git a/Doc/XCode.emmx "b/Doc/\346\217\222\345\205\245\345\255\227\346\256\265.emmx"
similarity index 100%
rename from Doc/XCode.emmx
rename to "Doc/\346\217\222\345\205\245\345\255\227\346\256\265.emmx"
Binary files a/Doc/XCode.emmx and "b/Doc/\346\217\222\345\205\245\345\255\227\346\256\265.emmx" differ
diff --git "a/Doc/\346\225\260\346\215\256\346\250\241\345\236\213.emmx" "b/Doc/\346\225\260\346\215\256\346\250\241\345\236\213.emmx"
new file mode 100644
index 0000000..6b2053c
Binary files /dev/null and "b/Doc/\346\225\260\346\215\256\346\250\241\345\236\213.emmx" differ
diff --git a/XCode/Attributes/BindTableAttribute.cs b/XCode/Attributes/BindTableAttribute.cs
index e001724..9a9d9dc 100644
--- a/XCode/Attributes/BindTableAttribute.cs
+++ b/XCode/Attributes/BindTableAttribute.cs
@@ -6,27 +6,23 @@ namespace XCode;
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class BindTableAttribute : Attribute
{
- /// <summary>
- /// 表名。
- /// 可以在配置文件中通过XCode.ConnMaps把实体映射到别的数据表上
- /// </summary>
+ /// <summary>表名</summary>
public String Name { get; set; }
/// <summary>描述</summary>
public String? Description { get; set; }
- /// <summary>
- /// 连接名。
+ /// <summary>连接名</summary>
+ /// <remarks>
/// 实体类的所有数据库操作,将发生在该连接名指定的数据库连接上。
/// 此外,可动态修改实体类在当前线程上的连接名(改Meta.ConnName);
- /// 也可以在配置文件中通过XCode.ConnMaps把连接名映射到别的连接上。
- /// </summary>
+ /// </remarks>
public String? ConnName { get; set; }
- /// <summary>
- /// 数据库类型。
+ /// <summary>数据库类型</summary>
+ /// <remarks>
/// 仅用于记录实体类由何种类型数据库生成,当且仅当目标数据库同为该数据库类型时,采用实体属性信息上的RawType作为反向工程的目标字段类型,以期获得开发和生产的最佳兼容。
- /// </summary>
+ /// </remarks>
public DatabaseType DbType { get; set; }
/// <summary>是否视图</summary>
@@ -34,10 +30,7 @@ public sealed class BindTableAttribute : Attribute
/// <summary>构造函数</summary>
/// <param name="name">表名</param>
- public BindTableAttribute(String name)
- {
- Name = name;
- }
+ public BindTableAttribute(String name) => Name = name;
/// <summary>构造函数</summary>
/// <param name="name">表名</param>
diff --git a/XCode/Configuration/FieldItem.cs b/XCode/Configuration/FieldItem.cs
index 4574e41..9015243 100644
--- a/XCode/Configuration/FieldItem.cs
+++ b/XCode/Configuration/FieldItem.cs
@@ -45,7 +45,7 @@ public class FieldItem
var name = Description;
if (name.IsNullOrEmpty()) return Name;
- var p = name.IndexOfAny(new[] { '。', ',' });
+ var p = name.IndexOfAny(['。', ',']);
if (p > 0) name = name[..p];
return name;
@@ -84,7 +84,7 @@ public class FieldItem
public Boolean PrimaryKey { get; internal set; }
/// <summary>是否主字段。主字段作为业务主要字段,代表当前数据行意义</summary>
- public Boolean Master { get; private set; }
+ public Boolean Master { get; internal set; }
/// <summary>是否允许空</summary>
public Boolean IsNullable { get; internal set; }
@@ -99,7 +99,7 @@ public class FieldItem
public Boolean IsDynamic => _Property == null;
/// <summary>字段名要过滤掉的标识符,考虑MSSQL、MySql、SQLite、Oracle等</summary>
- static readonly Char[] COLUMNNAME_FLAG = new Char[] { '[', ']', '\'', '"', '`' };
+ static readonly Char[] COLUMNNAME_FLAG = ['[', ']', '\'', '"', '`'];
private String? _ColumnName;
/// <summary>用于数据绑定的字段名</summary>
@@ -113,23 +113,14 @@ public class FieldItem
/// <remarks>set { _ReadOnly = value; } 放出只读属性的设置,比如在编辑页面的时候,有的字段不能修改 如修改用户时 不能修改用户名</remarks>
public Boolean ReadOnly { get; set; }
- /// <summary>表</summary>
+ /// <summary>表定义。来自实体类特性</summary>
public TableItem Table { get; internal protected set; } = null!;
/// <summary>字段</summary>
public IDataColumn Field { get; private set; } = null!;
/// <summary>实体操作者</summary>
- public IEntityFactory? Factory
- {
- get
- {
- var type = Table?.EntityType;
- if (type == null || type.IsInterface) return null;
-
- return type.AsFactory();
- }
- }
+ public IEntityFactory? Factory => Table?.EntityType.AsFactory();
/// <summary>已格式化的字段名,可字节用于SQL中。主要用于处理关键字,比如MSSQL里面的[User]</summary>
public String? FormatedName => Field == null ? null : Factory?.Session.Dal.Db.FormatName(Field);
diff --git a/XCode/Configuration/TableItem.cs b/XCode/Configuration/TableItem.cs
index 884ab8f..016feaa 100644
--- a/XCode/Configuration/TableItem.cs
+++ b/XCode/Configuration/TableItem.cs
@@ -22,26 +22,34 @@ public class TableItem
/// <summary>绑定索引特性</summary>
private readonly BindIndexAttribute[] _Indexes;
+ private String? _description;
private readonly DescriptionAttribute? _Description;
/// <summary>说明</summary>
public String? Description
{
get
{
- if (_Description != null && !String.IsNullOrEmpty(_Description.Description)) return _Description.Description;
- if (_Table != null && !String.IsNullOrEmpty(_Table.Description)) return _Table.Description;
+ if (_description != null) return _description;
- return null;
+ if (_Description != null && !String.IsNullOrEmpty(_Description.Description)) return _description = _Description.Description;
+ if (_Table != null && !String.IsNullOrEmpty(_Table.Description)) return _description = _Table.Description;
+
+ return _description;
}
}
#endregion
#region 属性
- /// <summary>默认表名。来自实体类特性</summary>
- public String TableName => _Table?.Name ?? EntityType.Name;
+ private String? _tableName;
+ /// <summary>表名。来自实体类特性,合并文件模型</summary>
+ public String TableName => _tableName ??= _Table?.Name ?? EntityType.Name;
+
+ /// <summary>原始表名</summary>
+ public String RawTableName => _Table?.Name ?? EntityType.Name;
- /// <summary>默认连接名。来自实体类特性</summary>
- public String ConnName => _Table?.ConnName + "";
+ private String? _connName;
+ /// <summary>连接名。来自实体类特性,合并文件模型</summary>
+ public String ConnName => _connName ??= _Table?.ConnName + "";
#endregion
#region 扩展属性
@@ -137,20 +145,35 @@ public class TableItem
InitFields();
}
- private static readonly ConcurrentDictionary<Type, TableItem> _cache = new();
- /// <summary>创建</summary>
+ private static readonly ConcurrentDictionary<String, TableItem> _cache = new();
+ /// <summary>创建数据表元数据信息。并合并连接名上的文件模型映射</summary>
/// <param name="type">类型</param>
+ /// <param name="connName">连接名。该类型的架构信息,则不同连接上可能存在文件模型映射,导致不一致</param>
/// <returns></returns>
- public static TableItem Create(Type type)
+ public static TableItem Create(Type type, String? connName)
{
if (type == null) throw new ArgumentNullException(nameof(type));
- if (_cache.TryGetValue(type, out var tableItem)) return tableItem;
+ var key = $"{type.FullName}#{connName}";
+ if (_cache.TryGetValue(key, out var tableItem)) return tableItem;
+ // 不能给没有BindTableAttribute特性的类型创建TableItem,否则可能会在InitFields中抛出异常
if (type.GetCustomAttribute<BindTableAttribute>(true) == null) throw new ArgumentOutOfRangeException(nameof(type));
- // 不能给没有BindTableAttribute特性的类型创建TableItem,否则可能会在InitFields中抛出异常
- return _cache.GetOrAdd(type, key => new TableItem(key));
+ // 先创建,然后合并外部文件模型
+ var ti = new TableItem(type);
+
+ if (connName.IsNullOrEmpty()) connName = ti.ConnName;
+ if (!connName.IsNullOrEmpty())
+ {
+ // 根据默认连接名找到目标文件模型,如果存在则合并
+ var table = DAL.Create(connName).ModelTables.FirstOrDefault(e => e.Name == ti.EntityType.Name);
+ if (table != null) ti.Merge(table);
+ }
+
+ ti._connName = connName;
+
+ return _cache.GetOrAdd(key, ti);
}
private void InitFields()
@@ -334,6 +357,68 @@ public class TableItem
#endregion
#region 方法
+ /// <summary>合并目标表到当前元数据</summary>
+ /// <param name="table"></param>
+ public void Merge(IDataTable table)
+ {
+ table = (table.Clone() as IDataTable)!;
+ if (table == null) return;
+
+ DataTable = table;
+
+ // 合并字段
+ _tableName = table.TableName;
+ _description = table.Description;
+
+ var allfields = AllFields.ToList();
+ var fields = Fields.ToList();
+ var pkeys = new List<FieldItem>();
+ foreach (var column in table.Columns)
+ {
+ if (column.Name.IsNullOrEmpty()) continue;
+
+ var fi = fields.FirstOrDefault(e => e.Name.EqualIgnoreCase(column.Name));
+ if (fi is null)
+ {
+ fi = new Field(this, column.Name, column.DataType!, column.Description, column.Length)
+ {
+ ColumnName = column.ColumnName,
+ IsNullable = column.Nullable,
+ IsIdentity = column.Identity,
+ PrimaryKey = column.PrimaryKey,
+ Master = column.Master,
+ DisplayName = column.DisplayName,
+ Description = column.Description,
+ //Map = column.Map,
+ IsDataObjectField = true
+ };
+
+ fields.Add(fi);
+
+ if (!allfields.Any(e => e.Name.EqualIgnoreCase(column.Name)))
+ allfields.Add(fi);
+ }
+ else
+ {
+ fi.ColumnName = column.ColumnName;
+ fi.IsNullable = column.Nullable;
+ fi.IsIdentity = column.Identity;
+ fi.PrimaryKey = column.PrimaryKey;
+ fi.Master = column.Master;
+ fi.DisplayName = column.DisplayName;
+ fi.Description = column.Description;
+ }
+
+ if (fi.PrimaryKey) pkeys.Add(fi);
+ if (fi.IsIdentity) Identity = fi;
+ if (fi.Master) Master = fi;
+ }
+
+ Fields = fields.ToArray();
+ AllFields = allfields.ToArray();
+ PrimaryKeys = pkeys.ToArray();
+ }
+
private IDictionary<String, Field?> _all;
/// <summary>根据名称查找</summary>
@@ -398,28 +483,28 @@ public class TableItem
#endregion
#region 动态增加字段
- /// <summary>动态增加字段</summary>
- /// <param name="name"></param>
- /// <param name="type"></param>
- /// <param name="description"></param>
- /// <param name="length"></param>
- /// <returns></returns>
- public TableItem Add(String name, Type type, String? description = null, Int32 length = 0)
- {
- var f = new Field(this, name, type, description, length);
+ ///// <summary>动态增加字段</summary>
+ ///// <param name="name"></param>
+ ///// <param name="type"></param>
+ ///// <param name="description"></param>
+ ///// <param name="length"></param>
+ ///// <returns></returns>
+ //public TableItem Add(String name, Type type, String? description = null, Int32 length = 0)
+ //{
+ // var f = new Field(this, name, type, description, length);
- var list = new List<FieldItem>(Fields) { f };
- Fields = list.ToArray();
+ // var list = new List<FieldItem>(Fields) { f };
+ // Fields = list.ToArray();
- list = new List<FieldItem>(AllFields) { f };
- AllFields = list.ToArray();
+ // list = new List<FieldItem>(AllFields) { f };
+ // AllFields = list.ToArray();
- var dc = DataTable.CreateColumn();
- f.Fill(dc);
+ // var dc = DataTable.CreateColumn();
+ // f.Fill(dc);
- DataTable.Columns.Add(dc);
+ // DataTable.Columns.Add(dc);
- return this;
- }
+ // return this;
+ //}
#endregion
}
\ No newline at end of file
diff --git a/XCode/Entity/Entity_Meta.cs b/XCode/Entity/Entity_Meta.cs
index c09861b..0169350 100644
--- a/XCode/Entity/Entity_Meta.cs
+++ b/XCode/Entity/Entity_Meta.cs
@@ -38,9 +38,9 @@ public partial class Entity<TEntity>
#endregion
#region 基本属性
- private static readonly Lazy<TableItem> _Table = new(() => TableItem.Create(ThisType));
- /// <summary>表信息。来自实体类</summary>
- public static TableItem Table => _Table.Value;
+ private static TableItem? _Table;
+ /// <summary>数据表元数据信息。来自实体类,并合并默认连接名上的文件模型</summary>
+ public static TableItem Table { get => _Table ??= TableItem.Create(ThisType, null); set => _Table = value; }
#if NET45
private static readonly ThreadLocal<String?> _ConnName = new();
diff --git a/XCode/Entity/EntityExtension.cs b/XCode/Entity/EntityExtension.cs
index ee5ba9a..ab6a93f 100644
--- a/XCode/Entity/EntityExtension.cs
+++ b/XCode/Entity/EntityExtension.cs
@@ -268,7 +268,7 @@ public static class EntityExtension
{
// 没有其它唯一索引,且主键为空时,走批量插入
var rs = 0;
- if (!session.Table.Indexes.Any(di => di.Unique))
+ if (!session.DataTable.Indexes.Any(di => di.Unique))
{
var inserts = new List<T>();
var updates = new List<T>();
@@ -501,7 +501,7 @@ public static class EntityExtension
using var span = tracer?.NewSpan($"db:{dal.ConnName}:BatchInsert:{fact.Table.TableName}", $"{session.TableName}[{list.Count()}]", list.Count());
try
{
- var rs = dal.Session.Insert(session.Table, option.Columns, list.Cast<IModel>());
+ var rs = dal.Session.Insert(session.DataTable, option.Columns, list.Cast<IModel>());
// 清除脏数据,避免重复提交保存
foreach (var item in list)
@@ -583,7 +583,7 @@ public static class EntityExtension
{
//if (span != null && list is ICollection collection) span.Tag = $"{session.TableName}[{collection.Count}]";
- var rs = dal.Session.InsertIgnore(session.Table, option.Columns, list.Cast<IModel>());
+ var rs = dal.Session.InsertIgnore(session.DataTable, option.Columns, list.Cast<IModel>());
// 清除脏数据,避免重复提交保存
foreach (var item in list)
@@ -665,7 +665,7 @@ public static class EntityExtension
{
//if (span != null && list is ICollection collection) span.Tag = $"{session.TableName}[{collection.Count}]";
- var rs = dal.Session.Replace(session.Table, option.Columns, list.Cast<IModel>());
+ var rs = dal.Session.Replace(session.DataTable, option.Columns, list.Cast<IModel>());
// 清除脏数据,避免重复提交保存
foreach (var item in list)
@@ -749,7 +749,7 @@ public static class EntityExtension
{
//if (span != null && list is ICollection collection) span.Tag = $"{session.TableName}[{collection.Count}]";
- var rs = dal.Session.Update(session.Table, option.Columns, updateColumns, addColumns, list.Cast<IModel>());
+ var rs = dal.Session.Update(session.DataTable, option.Columns, updateColumns, addColumns, list.Cast<IModel>());
// 清除脏数据,避免重复提交保存
foreach (var item in list)
@@ -888,7 +888,7 @@ public static class EntityExtension
{
//if (span != null && list is ICollection collection) span.Tag = $"{session.TableName}[{collection.Count}]";
- var rs = dal.Session.Upsert(session.Table, option.Columns, updateColumns, addColumns, list.Cast<IModel>());
+ var rs = dal.Session.Upsert(session.DataTable, option.Columns, updateColumns, addColumns, list.Cast<IModel>());
// 清除脏数据,避免重复提交保存
foreach (var item in list)
@@ -972,7 +972,7 @@ public static class EntityExtension
{
if (span != null) span.Tag = $"{session.TableName}[{entity}]";
- return dal.Session.Upsert(session.Table, option.Columns, option.UpdateColumns, option.AddColumns, [entity as IModel]);
+ return dal.Session.Upsert(session.DataTable, option.Columns, option.UpdateColumns, option.AddColumns, [entity as IModel]);
}
catch (Exception ex)
{
diff --git a/XCode/Entity/EntityFactory.cs b/XCode/Entity/EntityFactory.cs
index e601b0a..a7f42ac 100644
--- a/XCode/Entity/EntityFactory.cs
+++ b/XCode/Entity/EntityFactory.cs
@@ -110,31 +110,31 @@ public static class EntityFactory
var dic = new Dictionary<String, Type>(StringComparer.OrdinalIgnoreCase);
var list = new List<String>();
var list2 = new List<String>();
- foreach (var item in LoadEntities(connName))
+ foreach (var type in LoadEntities(connName))
{
- list.Add(item.Name);
+ list.Add(type.Name);
// 过滤掉第一次使用才加载的
if (checkMode)
{
- var att = item.GetCustomAttribute<ModelCheckModeAttribute>(true);
+ var att = type.GetCustomAttribute<ModelCheckModeAttribute>(true);
if (att != null && att.Mode != ModelCheckModes.CheckAllTablesWhenInit) continue;
}
- list2.Add(item.Name);
+ list2.Add(type.Name);
- var table = TableItem.Create(item).DataTable;
+ var table = TableItem.Create(type, connName).DataTable;
// 判断表名是否已存在
- if (dic.TryGetValue(table.TableName, out var type))
+ if (dic.TryGetValue(table.TableName, out var oldType))
{
// 两个都不是,报错吧!
- var msg = $"设计错误!发现表{table.TableName}同时被两个实体类({type.FullName}和{item.FullName})使用!";
+ var msg = $"设计错误!发现表{table.TableName}同时被两个实体类({oldType.FullName}和{type.FullName})使用!";
XTrace.WriteLine(msg);
throw new XCodeException(msg);
}
else
{
- dic.Add(table.TableName, item);
+ dic.Add(table.TableName, type);
}
tables.Add(table);
diff --git a/XCode/Entity/EntitySession.cs b/XCode/Entity/EntitySession.cs
index bb6bc6f..06d3f9e 100644
--- a/XCode/Entity/EntitySession.cs
+++ b/XCode/Entity/EntitySession.cs
@@ -75,13 +75,18 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
TableName = tableName;
Key = connName + "###" + tableName;
- TableItem = TableItem.Create(ThisType);
- Table = (TableItem.DataTable.Clone() as IDataTable)!;
- Table.TableName = tableName;
+ var ti = Table = TableItem.Create(ThisType, connName);
+ DataTable = (Table.DataTable.Clone() as IDataTable)!;
+
+ // 使用文件模型映射的表名
+ if (tableName == ti.RawTableName)
+ TableName = DataTable.TableName;
+ else
+ DataTable.TableName = tableName;
Queue = new EntityQueue(this)
{
- InsertOnly = Table.InsertOnly
+ InsertOnly = DataTable.InsertOnly
};
}
@@ -113,11 +118,11 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
#region 主要属性
private Type ThisType => typeof(TEntity);
- /// <summary>表信息</summary>
- TableItem TableItem { get; }
+ /// <summary>数据表元数据信息。合并连接上的文件模型,可能跟Meta.Table不一致</summary>
+ public TableItem Table { get; }
/// <summary>数据表</summary>
- public IDataTable Table { get; }
+ public IDataTable DataTable { get; }
IEntityFactory Factory { get; } = typeof(TEntity).AsFactory();
@@ -132,7 +137,7 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
{
get
{
- if (_FormatedTableName.IsNullOrEmpty()) _FormatedTableName = Dal.Db.FormatName(Table);
+ if (_FormatedTableName.IsNullOrEmpty()) _FormatedTableName = Dal.Db.FormatName(DataTable);
return _FormatedTableName;
}
@@ -146,8 +151,8 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
{
if (_Default != null) return _Default;
- var cname = TableItem.ConnName;
- var tname = TableItem.TableName;
+ var cname = Table.ConnName;
+ var tname = Table.TableName;
if (ConnName == cname && TableName == tname)
_Default = this;
@@ -174,7 +179,7 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
public Boolean WaitForInitData(Int32 ms = 3000)
{
// 已初始化
- if (hasCheckInitData || Table.IsView) return true;
+ if (hasCheckInitData || DataTable.IsView) return true;
var tid = Thread.CurrentThread.ManagedThreadId;
@@ -232,7 +237,7 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
var dal = Dal;
// 检查新表名对应的数据表
- var table = TableItem.DataTable;
+ var table = Table.DataTable;
// 克隆一份,防止修改
table = (table.Clone() as IDataTable)!;
@@ -254,7 +259,7 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
/// <summary>检查模型。依据反向工程设置、是否首次使用检查、是否已常规检查等</summary>
private void CheckModel()
{
- if (_hasCheckModel || Table.IsView) return;
+ if (_hasCheckModel || DataTable.IsView) return;
lock (_checkLock)
{
if (_hasCheckModel) return;
@@ -269,7 +274,7 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
}
// CheckTableWhenFirstUse的实体类,在这里检查,有点意思,记下来
- var mode = TableItem.ModelCheckMode;
+ var mode = Table.ModelCheckMode;
if (DAL.Debug && mode == ModelCheckModes.CheckTableWhenFirstUse)
DAL.WriteLog("检查实体{0}的数据表架构,模式:{1}", ThisType.FullName, mode);
@@ -446,12 +451,12 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
var dal = Dal;
// 第一次访问,SQLite的Select Count非常慢,数据大于阀值时,使用最大ID作为表记录数
- if (count < 0 && dal.DbType == DatabaseType.SQLite && TableItem.Identity != null)
+ if (count < 0 && dal.DbType == DatabaseType.SQLite && Table.Identity != null)
{
var builder = new SelectBuilder
{
Table = FormatedTableName,
- OrderBy = TableItem.Identity.Desc()
+ OrderBy = Table.Identity.Desc()
};
FixBuilder(builder);
var ds = dal.Query(builder, 0, 1);
@@ -460,7 +465,7 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
}
// 100w数据时,没有预热Select Count需要3000ms,预热后需要500ms
- if (dal.DbType != DatabaseType.SQLite && (count <= 0 || count >= 1_000_000) && !Table.IsView)
+ if (dal.DbType != DatabaseType.SQLite && (count <= 0 || count >= 1_000_000) && !DataTable.IsView)
{
using var span = dal.Tracer?.NewSpan($"db:{ConnName}:QueryCountFast:{TableName}");
try
@@ -607,7 +612,7 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
private void FixBuilder(SelectBuilder builder)
{
- if (Table.IsView && builder.Table == FormatedTableName)
+ if (DataTable.IsView && builder.Table == FormatedTableName)
{
builder.Table = $"({Factory.Template.GetSql(Dal.DbType)}) SourceTable";
}
@@ -812,7 +817,7 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
/// <returns></returns>
public virtual Int32 Insert(IEntity entity)
{
- if (Table.IsView) throw new NotSupportedException("视图无法添删改!");
+ if (DataTable.IsView) throw new NotSupportedException("视图无法添删改!");
var rs = Factory.Persistence.Insert(this, entity);
@@ -836,7 +841,7 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
/// <returns></returns>
public virtual Int32 Update(IEntity entity)
{
- if (Table.IsView) throw new NotSupportedException("视图无法添删改!");
+ if (DataTable.IsView) throw new NotSupportedException("视图无法添删改!");
var rs = Factory.Persistence.Update(this, entity);
@@ -859,7 +864,7 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
/// <returns></returns>
public virtual Int32 Delete(IEntity entity)
{
- if (Table.IsView) throw new NotSupportedException("视图无法添删改!");
+ if (DataTable.IsView) throw new NotSupportedException("视图无法添删改!");
var rs = Factory.Persistence.Delete(this, entity);
@@ -885,7 +890,7 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
/// <returns></returns>
public virtual async Task<Int32> InsertAsync(IEntity entity)
{
- if (Table.IsView) throw new NotSupportedException("视图无法添删改!");
+ if (DataTable.IsView) throw new NotSupportedException("视图无法添删改!");
var rs = await Factory.Persistence.InsertAsync(this, entity);
@@ -905,7 +910,7 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
/// <returns></returns>
public virtual Task<Int32> UpdateAsync(IEntity entity)
{
- if (Table.IsView) throw new NotSupportedException("视图无法添删改!");
+ if (DataTable.IsView) throw new NotSupportedException("视图无法添删改!");
var rs = Factory.Persistence.UpdateAsync(this, entity);
@@ -925,7 +930,7 @@ public class EntitySession<TEntity> : DisposeBase, IEntitySession where TEntity
/// <returns></returns>
public virtual Task<Int32> DeleteAsync(IEntity entity)
{
- if (Table.IsView) throw new NotSupportedException("视图无法添删改!");
+ if (DataTable.IsView) throw new NotSupportedException("视图无法添删改!");
var rs = Factory.Persistence.DeleteAsync(this, entity);
diff --git a/XCode/Entity/IEntitySession.cs b/XCode/Entity/IEntitySession.cs
index d1eec40..6780f5f 100644
--- a/XCode/Entity/IEntitySession.cs
+++ b/XCode/Entity/IEntitySession.cs
@@ -16,7 +16,7 @@ public interface IEntitySession
String TableName { get; }
/// <summary>数据表</summary>
- IDataTable Table { get; }
+ IDataTable DataTable { get; }
/// <summary>用于标识会话的键值</summary>
String Key { get; }
diff --git a/XCode/Model/FieldExpression.cs b/XCode/Model/FieldExpression.cs
index 8c5111f..087df90 100644
--- a/XCode/Model/FieldExpression.cs
+++ b/XCode/Model/FieldExpression.cs
@@ -50,7 +50,7 @@ public class FieldExpression : Expression
if (Field == null) return;
// 部分场景外部未能传入数据库,此时内部尽力获取
- db ??= Field?.Factory.Session.Dal.Db;
+ db ??= Field?.Factory?.Session.Dal.Db ?? throw new ArgumentNullException(nameof(db));
var columnName = db.FormatName(Field.Field);
if (Action.IsNullOrEmpty())
diff --git a/XCode/Model/FormatExpression.cs b/XCode/Model/FormatExpression.cs
index 21203ee..0cdea4a 100644
--- a/XCode/Model/FormatExpression.cs
+++ b/XCode/Model/FormatExpression.cs
@@ -51,7 +51,7 @@ public class FormatExpression : Expression
if (Field == null || Format.IsNullOrWhiteSpace()) return;
// 部分场景外部未能传入数据库,此时内部尽力获取
- if (db == null) db = Field?.Factory.Session.Dal.Db;
+ db ??= Field?.Factory?.Session.Dal.Db ?? throw new ArgumentNullException(nameof(db));
var columnName = db.FormatName(Field.Field);
diff --git a/XCode/Model/InExpression.cs b/XCode/Model/InExpression.cs
index 0477f67..64a6206 100644
--- a/XCode/Model/InExpression.cs
+++ b/XCode/Model/InExpression.cs
@@ -52,7 +52,7 @@ namespace XCode
if (Field == null || Format.IsNullOrWhiteSpace()) return;
// 部分场景外部未能传入数据库,此时内部尽力获取
- if (db == null) db = Field?.Factory.Session.Dal.Db;
+ db ??= Field?.Factory?.Session.Dal.Db ?? throw new ArgumentNullException(nameof(db));
var column = Field.Field;
var columnName = db.FormatName(Field.Field);
diff --git a/XCode/Model/LikeExpression.cs b/XCode/Model/LikeExpression.cs
index 38bb38b..6d3704e 100644
--- a/XCode/Model/LikeExpression.cs
+++ b/XCode/Model/LikeExpression.cs
@@ -50,7 +50,7 @@ namespace XCode
if (Field == null || Format.IsNullOrWhiteSpace()) return;
// 部分场景外部未能传入数据库,此时内部尽力获取
- if (db == null) db = Field?.Factory.Session.Dal.Db;
+ db ??= Field?.Factory?.Session.Dal.Db ?? throw new ArgumentNullException(nameof(db));
var columnName = db.FormatName(Field.Field);
diff --git a/XUnitTest.XCode/Configuration/TableItemTests.cs b/XUnitTest.XCode/Configuration/TableItemTests.cs
index 7308ea2..45753a4 100644
--- a/XUnitTest.XCode/Configuration/TableItemTests.cs
+++ b/XUnitTest.XCode/Configuration/TableItemTests.cs
@@ -3,16 +3,15 @@ using XCode.Configuration;
using Xunit;
using XUnitTest.XCode.TestEntity;
-namespace XUnitTest.XCode.Configuration
+namespace XUnitTest.XCode.Configuration;
+
+public class TableItemTests
{
- public class TableItemTests
+ [Fact]
+ public void TrimIndex()
{
- [Fact]
- public void TrimIndex()
- {
- var ti = TableItem.Create(typeof(Log2));
- XTrace.WriteLine(ti.TableName);
- Assert.Equal(4, ti.DataTable.Indexes.Count);
- }
+ var ti = TableItem.Create(typeof(Log2), null);
+ XTrace.WriteLine(ti.TableName);
+ Assert.Equal(4, ti.DataTable.Indexes.Count);
}
}
\ No newline at end of file
diff --git a/XUnitTest.XCode/DataAccessLayer/DALTests.cs b/XUnitTest.XCode/DataAccessLayer/DALTests.cs
index d975855..ed8a377 100644
--- a/XUnitTest.XCode/DataAccessLayer/DALTests.cs
+++ b/XUnitTest.XCode/DataAccessLayer/DALTests.cs
@@ -147,6 +147,10 @@ public class DALTests
// 构建新的模型
var tb = Role.Meta.Table.DataTable.Clone() as IDataTable;
tb.TableName = "Role_mtt";
+
+ var column = tb.Columns.First(e => e.Name == "Name");
+ column.ColumnName = "Name_mtt";
+
var xml = DAL.Export([tb]);
File.WriteAllText(file.EnsureDirectory(true), xml);
@@ -161,7 +165,11 @@ public class DALTests
using var st = Role.Meta.CreateSplit(name, null);
// 此时我们希望实体类拿到的数据表是新的
- var tb3 = Role.Meta.Table.DataTable;
- Assert.Equal(tb.TableName, tb3.TableName);
+ //var tb3 = Role.Meta.Table.DataTable;
+ Assert.Equal(tb.TableName, Role.Meta.Session.Table.TableName);
+ Assert.Equal(tb.TableName, Role.Meta.Session.DataTable.TableName);
+ Assert.Equal(tb.TableName, Role.Meta.Session.TableName);
+ //Assert.Equal(tb.TableName, Role.Meta.TableName);
+ Assert.Equal("Name_mtt", Role.Meta.Session.Table.FindByName("Name").ColumnName);
}
}
\ No newline at end of file