- 增加 TableAttribute 特性属性 DisableSyncStructure,当实体对应的是视图时,可使用本功能禁用迁移 #61;

- 增加 FreeSqlBuilder UseEntityPropertyNameConvert() 全局转换实体属性名方法 #60;
This commit is contained in:
28810 2019-06-13 20:04:08 +08:00
parent ab658ca49e
commit 38d51a809d
18 changed files with 180 additions and 79 deletions

View File

@ -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>

View File

@ -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));

View File

@ -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

View File

@ -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);
}
}

View File

@ -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}");

View File

@ -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>

View File

@ -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>
测量两个经纬度的距离,返回单位:米

View File

@ -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;
}

View File

@ -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;

View File

@ -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) {

View File

@ -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; }

View File

@ -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) {

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>