mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 10:42:52 +08:00
- 增加 TableAttribute 特性属性 DisableSyncStructure,当实体对应的是视图时,可使用本功能禁用迁移 #61;
- 增加 FreeSqlBuilder UseEntityPropertyNameConvert() 全局转换实体属性名方法 #60;
This commit is contained in:
parent
ab658ca49e
commit
38d51a809d
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
|
||||
<Version>0.6.9</Version>
|
||||
<Version>0.6.10</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 扩展包,可实现【延时加载】属性.</Description>
|
||||
|
@ -1,4 +1,5 @@
|
||||
using FreeSql.DataAnnotations;
|
||||
using MySql.Data.MySqlClient;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
@ -9,6 +10,22 @@ namespace FreeSql.Tests.DataAnnotations {
|
||||
public MySqlFluentTest() {
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DisableSyncStructure() {
|
||||
Assert.Throws<MySqlException>(() => g.mysql.Select<ModelDisableSyncStructure>().ToList());
|
||||
|
||||
g.mysql.Select<ModelSyncStructure>().ToList();
|
||||
}
|
||||
[Table(DisableSyncStructure = true)]
|
||||
class ModelDisableSyncStructure {
|
||||
[Column(IsPrimary = false)]
|
||||
public int pkid { get; set; }
|
||||
}
|
||||
class ModelSyncStructure {
|
||||
[Column(IsPrimary = false)]
|
||||
public int pkid { get; set; }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AopConfigEntity() {
|
||||
g.mysql.CodeFirst.ConfigEntity<ModelAopConfigEntity>(a => a.Property(b => b.pkid).IsPrimary(true));
|
||||
|
@ -1,6 +1,7 @@
|
||||
using FreeSql.DataAnnotations;
|
||||
using FreeSql.Tests.DataContext.SqlServer;
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using Xunit;
|
||||
|
||||
namespace FreeSql.Tests.DataAnnotations {
|
||||
@ -14,6 +15,22 @@ namespace FreeSql.Tests.DataAnnotations {
|
||||
_sqlserverFixture = sqlserverFixture;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DisableSyncStructure() {
|
||||
Assert.Throws<SqlException>(() => _sqlserverFixture.SqlServer.Select<ModelDisableSyncStructure>().ToList());
|
||||
|
||||
_sqlserverFixture.SqlServer.Select<ModelSyncStructure>().ToList();
|
||||
}
|
||||
[Table(DisableSyncStructure = true)]
|
||||
class ModelDisableSyncStructure {
|
||||
[Column(IsPrimary = false)]
|
||||
public int pkid { get; set; }
|
||||
}
|
||||
class ModelSyncStructure {
|
||||
[Column(IsPrimary = false)]
|
||||
public int pkid { get; set; }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Fluent() {
|
||||
_sqlserverFixture.SqlServer.CodeFirst
|
||||
|
@ -17,6 +17,12 @@ namespace FreeSql.DataAnnotations {
|
||||
/// </summary>
|
||||
public string SelectFilter { get; set; }
|
||||
|
||||
internal bool? _DisableSyncStructure;
|
||||
/// <summary>
|
||||
/// 禁用 CodeFirst 同步结构迁移
|
||||
/// </summary>
|
||||
public bool DisableSyncStructure { get => _DisableSyncStructure ?? false; set => _DisableSyncStructure = value; }
|
||||
|
||||
internal ConcurrentDictionary<string, ColumnAttribute> _columns { get; } = new ConcurrentDictionary<string, ColumnAttribute>(StringComparer.CurrentCultureIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,14 @@ namespace FreeSql.DataAnnotations {
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 禁用 CodeFirst 同步结构迁移
|
||||
/// </summary>
|
||||
public TableFluent DisableSyncStructure(bool value) {
|
||||
_table.DisableSyncStructure = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ColumnFluent Property(string proto) {
|
||||
if (_properties.ContainsKey(proto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}");
|
||||
var col = _table._columns.GetOrAdd(proto, name => new ColumnAttribute { Name = proto });
|
||||
@ -74,6 +82,14 @@ namespace FreeSql.DataAnnotations {
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 禁用 CodeFirst 同步结构迁移
|
||||
/// </summary>
|
||||
public TableFluent<T> DisableSyncStructure(bool value) {
|
||||
_table.DisableSyncStructure = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ColumnFluent Property<TProto>(Expression<Func<T, TProto>> column) {
|
||||
var proto = (column.Body as MemberExpression)?.Member;
|
||||
if (proto == null) throw new FormatException($"错误的表达式格式 {column}");
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
|
||||
<Version>0.6.9</Version>
|
||||
<Version>0.6.10</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>
|
||||
|
@ -133,6 +133,11 @@
|
||||
查询过滤SQL,实现类似 a.IsDeleted = 1 功能
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:FreeSql.DataAnnotations.TableAttribute.DisableSyncStructure">
|
||||
<summary>
|
||||
禁用 CodeFirst 同步结构迁移
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:FreeSql.DataAnnotations.TableFluent.Name(System.String)">
|
||||
<summary>
|
||||
数据库表名
|
||||
@ -148,6 +153,11 @@
|
||||
查询过滤SQL,实现类似 a.IsDeleted = 1 功能
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:FreeSql.DataAnnotations.TableFluent.DisableSyncStructure(System.Boolean)">
|
||||
<summary>
|
||||
禁用 CodeFirst 同步结构迁移
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:FreeSql.DataAnnotations.TableFluent`1.Name(System.String)">
|
||||
<summary>
|
||||
数据库表名
|
||||
@ -163,6 +173,11 @@
|
||||
查询过滤SQL,实现类似 a.IsDeleted = 1 功能
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:FreeSql.DataAnnotations.TableFluent`1.DisableSyncStructure(System.Boolean)">
|
||||
<summary>
|
||||
禁用 CodeFirst 同步结构迁移
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:FreeSql.DatabaseModel.DbColumnInfo.Table">
|
||||
<summary>
|
||||
所属表
|
||||
@ -480,6 +495,15 @@
|
||||
<param name="executed">执行后,可监视执行性能</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.FreeSqlBuilder.UseEntityPropertyNameConvert(FreeSql.Internal.StringConvertType)">
|
||||
<summary>
|
||||
自动转换实体属性名称 Entity Property -> Db Filed
|
||||
<para></para>
|
||||
*不会覆盖 [Column] 特性设置的Name
|
||||
</summary>
|
||||
<param name="convertType"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.IDelete`1.WithTransaction(System.Data.Common.DbTransaction)">
|
||||
<summary>
|
||||
指定事务对象
|
||||
@ -2251,6 +2275,55 @@
|
||||
中间表,多对多
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:FreeSql.Internal.StringConvertType.None">
|
||||
<summary>
|
||||
不进行任何处理
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:FreeSql.Internal.StringConvertType.PascalCaseToUnderscore">
|
||||
<summary>
|
||||
将帕斯卡命名字符串转换为下划线分隔字符串
|
||||
<para></para>
|
||||
BigApple -> Big_Apple
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:FreeSql.Internal.StringConvertType.PascalCaseToUnderscoreWithUpper">
|
||||
<summary>
|
||||
将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写
|
||||
<para></para>
|
||||
BigApple -> BIG_APPLE
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:FreeSql.Internal.StringConvertType.PascalCaseToUnderscoreWithLower">
|
||||
<summary>
|
||||
将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写
|
||||
<para></para>
|
||||
BigApple -> big_apple
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:FreeSql.Internal.StringConvertType.Upper">
|
||||
<summary>
|
||||
将字符串转换为大写
|
||||
<para></para>
|
||||
BigApple -> BIGAPPLE
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:FreeSql.Internal.StringConvertType.Lower">
|
||||
<summary>
|
||||
将字符串转换为小写
|
||||
<para></para>
|
||||
BigApple -> bigapple
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:FreeSql.Internal.StringUtils.PascalCaseToUnderScore(System.String)">
|
||||
<summary>
|
||||
将帕斯卡命名字符串转换为下划线分隔字符串
|
||||
<para></para>
|
||||
BigApple -> Big_Apple
|
||||
</summary>
|
||||
<param name="str"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSqlGlobalExtensions.Distance(System.Drawing.Point,System.Drawing.Point)">
|
||||
<summary>
|
||||
测量两个经纬度的距离,返回单位:米
|
||||
|
@ -157,73 +157,39 @@ namespace FreeSql {
|
||||
ado.AopCommandExecuting += _aopCommandExecuting;
|
||||
ado.AopCommandExecuted += _aopCommandExecuted;
|
||||
|
||||
//添加实体属性名全局AOP转换处理
|
||||
if (_entityPropertyConvertType != StringConvertType.None)
|
||||
{
|
||||
// 局部方法判断是否存在Column特性以及是否设置Name的值
|
||||
bool CheckEntityPropertyColumnAttribute(PropertyInfo propertyInfo)
|
||||
{
|
||||
var attr = propertyInfo.GetCustomAttribute<ColumnAttribute>();
|
||||
if (attr == null || string.IsNullOrEmpty(attr.Name))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (_entityPropertyConvertType)
|
||||
{
|
||||
case StringConvertType.Lower:
|
||||
ret.Aop.ConfigEntityProperty = (s, e) =>
|
||||
{
|
||||
if (CheckEntityPropertyColumnAttribute(e.Property))
|
||||
{
|
||||
e.ModifyResult.Name = e.Property.Name.ToLower();
|
||||
}
|
||||
};
|
||||
break;
|
||||
case StringConvertType.Upper:
|
||||
ret.Aop.ConfigEntityProperty = (s, e) =>
|
||||
{
|
||||
if (CheckEntityPropertyColumnAttribute(e.Property))
|
||||
{
|
||||
e.ModifyResult.Name = e.Property.Name.ToUpper();
|
||||
}
|
||||
};
|
||||
break;
|
||||
case StringConvertType.PascalCaseToUnderscore:
|
||||
ret.Aop.ConfigEntityProperty = (s, e) =>
|
||||
{
|
||||
if (CheckEntityPropertyColumnAttribute(e.Property))
|
||||
{
|
||||
e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name);
|
||||
}
|
||||
};
|
||||
break;
|
||||
case StringConvertType.PascalCaseToUnderscoreWithLower:
|
||||
ret.Aop.ConfigEntityProperty = (s, e) =>
|
||||
{
|
||||
if (CheckEntityPropertyColumnAttribute(e.Property))
|
||||
{
|
||||
e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToLower();
|
||||
}
|
||||
};
|
||||
break;
|
||||
case StringConvertType.PascalCaseToUnderscoreWithUpper:
|
||||
ret.Aop.ConfigEntityProperty = (s, e) =>
|
||||
{
|
||||
if (CheckEntityPropertyColumnAttribute(e.Property))
|
||||
{
|
||||
e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToUpper();
|
||||
}
|
||||
};
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//添加实体属性名全局AOP转换处理
|
||||
if (_entityPropertyConvertType != StringConvertType.None) {
|
||||
switch (_entityPropertyConvertType) {
|
||||
case StringConvertType.Lower:
|
||||
ret.Aop.ConfigEntityProperty = (s, e) => {
|
||||
e.ModifyResult.Name = e.Property.Name.ToLower();
|
||||
};
|
||||
break;
|
||||
case StringConvertType.Upper:
|
||||
ret.Aop.ConfigEntityProperty = (s, e) => {
|
||||
e.ModifyResult.Name = e.Property.Name.ToUpper();
|
||||
};
|
||||
break;
|
||||
case StringConvertType.PascalCaseToUnderscore:
|
||||
ret.Aop.ConfigEntityProperty = (s, e) => {
|
||||
e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name);
|
||||
};
|
||||
break;
|
||||
case StringConvertType.PascalCaseToUnderscoreWithLower:
|
||||
ret.Aop.ConfigEntityProperty = (s, e) => {
|
||||
e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToLower();
|
||||
};
|
||||
break;
|
||||
case StringConvertType.PascalCaseToUnderscoreWithUpper:
|
||||
ret.Aop.ConfigEntityProperty = (s, e) => {
|
||||
e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToUpper();
|
||||
};
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -45,9 +45,9 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
internal ConcurrentDictionary<string, bool> dicSyced = new ConcurrentDictionary<string, bool>();
|
||||
public bool SyncStructure<TEntity>() => this.SyncStructure(typeof(TEntity));
|
||||
public bool SyncStructure(params Type[] entityTypes) {
|
||||
if (entityTypes == null) return true;
|
||||
var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false).ToArray();
|
||||
if (syncTypes.Any() == false) return true;
|
||||
if (entityTypes == null) return false;
|
||||
var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false && GetTableByEntity(a)?.DisableSyncStructure == false).ToArray();
|
||||
if (syncTypes.Any() == false) return false;
|
||||
var before = new Aop.SyncStructureBeforeEventArgs(entityTypes);
|
||||
_orm.Aop.SyncStructureBefore?.Invoke(this, before);
|
||||
Exception exception = null;
|
||||
|
@ -73,6 +73,8 @@ namespace FreeSql.Internal {
|
||||
if (!string.IsNullOrEmpty(trytb.Name)) attr.Name = trytb.Name;
|
||||
if (!string.IsNullOrEmpty(trytb.OldName)) attr.OldName = trytb.OldName;
|
||||
if (!string.IsNullOrEmpty(trytb.SelectFilter)) attr.SelectFilter = trytb.SelectFilter;
|
||||
if (trytb._DisableSyncStructure != null) attr._DisableSyncStructure = trytb.DisableSyncStructure;
|
||||
|
||||
}
|
||||
var attrs = type.GetCustomAttributes(typeof(TableAttribute), false);
|
||||
foreach (var tryattrobj in attrs) {
|
||||
@ -81,10 +83,12 @@ namespace FreeSql.Internal {
|
||||
if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name;
|
||||
if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName;
|
||||
if (!string.IsNullOrEmpty(tryattr.SelectFilter)) attr.SelectFilter = tryattr.SelectFilter;
|
||||
if (tryattr._DisableSyncStructure != null) attr._DisableSyncStructure = tryattr.DisableSyncStructure;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(attr.Name)) return attr;
|
||||
if (!string.IsNullOrEmpty(attr.OldName)) return attr;
|
||||
if (!string.IsNullOrEmpty(attr.SelectFilter)) return attr;
|
||||
if (attr._DisableSyncStructure != null) return attr;
|
||||
return null;
|
||||
}
|
||||
public ColumnAttribute GetEntityColumnAttribute(Type type, PropertyInfo proto) {
|
||||
|
@ -18,6 +18,7 @@ namespace FreeSql.Internal.Model {
|
||||
public string DbName { get; set; }
|
||||
public string DbOldName { get; set; }
|
||||
public string SelectFilter { get; set; }
|
||||
public bool DisableSyncStructure { get; set; }
|
||||
|
||||
public ColumnInfo VersionColumn { get; set; }
|
||||
|
||||
|
@ -53,6 +53,7 @@ namespace FreeSql.Internal {
|
||||
trytb.DbOldName = trytb.DbOldName?.ToUpper();
|
||||
}
|
||||
trytb.SelectFilter = tbattr?.SelectFilter;
|
||||
if (tbattr != null) trytb.DisableSyncStructure = tbattr.DisableSyncStructure;
|
||||
var propsLazy = new List<(PropertyInfo, bool, bool)>();
|
||||
var propsNavObjs = new List<PropertyInfo>();
|
||||
foreach (var p in trytb.Properties.Values) {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net452</TargetFrameworks>
|
||||
<Version>0.6.9</Version>
|
||||
<Version>0.6.10</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 数据库实现,基于 MySql 5.6</Description>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
|
||||
<Version>0.6.9</Version>
|
||||
<Version>0.6.10</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 数据库实现,基于 MySql 5.6</Description>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
|
||||
<Version>0.6.9</Version>
|
||||
<Version>0.6.10</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 数据库实现,基于 Oracle 11</Description>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
|
||||
<Version>0.6.9</Version>
|
||||
<Version>0.6.10</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 数据库实现,基于 PostgreSQL 9.5</Description>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net451</TargetFrameworks>
|
||||
<Version>0.6.9</Version>
|
||||
<Version>0.6.10</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next</Description>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
|
||||
<Version>0.6.9</Version>
|
||||
<Version>0.6.10</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 数据库实现,基于 Sqlite 3.0</Description>
|
||||
|
Loading…
x
Reference in New Issue
Block a user