- 增加 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> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks> <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.6.9</Version> <Version>0.6.10</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors> <Authors>YeXiangQin</Authors>
<Description>FreeSql 扩展包,可实现【延时加载】属性.</Description> <Description>FreeSql 扩展包,可实现【延时加载】属性.</Description>

View File

@ -1,4 +1,5 @@
using FreeSql.DataAnnotations; using FreeSql.DataAnnotations;
using MySql.Data.MySqlClient;
using System; using System;
using System.Linq; using System.Linq;
using Xunit; using Xunit;
@ -9,6 +10,22 @@ namespace FreeSql.Tests.DataAnnotations {
public MySqlFluentTest() { 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] [Fact]
public void AopConfigEntity() { public void AopConfigEntity() {
g.mysql.CodeFirst.ConfigEntity<ModelAopConfigEntity>(a => a.Property(b => b.pkid).IsPrimary(true)); g.mysql.CodeFirst.ConfigEntity<ModelAopConfigEntity>(a => a.Property(b => b.pkid).IsPrimary(true));

View File

@ -1,6 +1,7 @@
using FreeSql.DataAnnotations; using FreeSql.DataAnnotations;
using FreeSql.Tests.DataContext.SqlServer; using FreeSql.Tests.DataContext.SqlServer;
using System; using System;
using System.Data.SqlClient;
using Xunit; using Xunit;
namespace FreeSql.Tests.DataAnnotations { namespace FreeSql.Tests.DataAnnotations {
@ -14,6 +15,22 @@ namespace FreeSql.Tests.DataAnnotations {
_sqlserverFixture = sqlserverFixture; _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] [Fact]
public void Fluent() { public void Fluent() {
_sqlserverFixture.SqlServer.CodeFirst _sqlserverFixture.SqlServer.CodeFirst

View File

@ -17,6 +17,12 @@ namespace FreeSql.DataAnnotations {
/// </summary> /// </summary>
public string SelectFilter { get; set; } 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); internal ConcurrentDictionary<string, ColumnAttribute> _columns { get; } = new ConcurrentDictionary<string, ColumnAttribute>(StringComparer.CurrentCultureIgnoreCase);
} }
} }

View File

@ -38,6 +38,14 @@ namespace FreeSql.DataAnnotations {
return this; return this;
} }
/// <summary>
/// 禁用 CodeFirst 同步结构迁移
/// </summary>
public TableFluent DisableSyncStructure(bool value) {
_table.DisableSyncStructure = value;
return this;
}
public ColumnFluent Property(string proto) { public ColumnFluent Property(string proto) {
if (_properties.ContainsKey(proto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}"); if (_properties.ContainsKey(proto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}");
var col = _table._columns.GetOrAdd(proto, name => new ColumnAttribute { Name = proto }); var col = _table._columns.GetOrAdd(proto, name => new ColumnAttribute { Name = proto });
@ -74,6 +82,14 @@ namespace FreeSql.DataAnnotations {
return this; 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) { public ColumnFluent Property<TProto>(Expression<Func<T, TProto>> column) {
var proto = (column.Body as MemberExpression)?.Member; var proto = (column.Body as MemberExpression)?.Member;
if (proto == null) throw new FormatException($"错误的表达式格式 {column}"); if (proto == null) throw new FormatException($"错误的表达式格式 {column}");

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks> <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.6.9</Version> <Version>0.6.10</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors> <Authors>YeXiangQin</Authors>
<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description> <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 功能 查询过滤SQL实现类似 a.IsDeleted = 1 功能
</summary> </summary>
</member> </member>
<member name="P:FreeSql.DataAnnotations.TableAttribute.DisableSyncStructure">
<summary>
禁用 CodeFirst 同步结构迁移
</summary>
</member>
<member name="M:FreeSql.DataAnnotations.TableFluent.Name(System.String)"> <member name="M:FreeSql.DataAnnotations.TableFluent.Name(System.String)">
<summary> <summary>
数据库表名 数据库表名
@ -148,6 +153,11 @@
查询过滤SQL实现类似 a.IsDeleted = 1 功能 查询过滤SQL实现类似 a.IsDeleted = 1 功能
</summary> </summary>
</member> </member>
<member name="M:FreeSql.DataAnnotations.TableFluent.DisableSyncStructure(System.Boolean)">
<summary>
禁用 CodeFirst 同步结构迁移
</summary>
</member>
<member name="M:FreeSql.DataAnnotations.TableFluent`1.Name(System.String)"> <member name="M:FreeSql.DataAnnotations.TableFluent`1.Name(System.String)">
<summary> <summary>
数据库表名 数据库表名
@ -163,6 +173,11 @@
查询过滤SQL实现类似 a.IsDeleted = 1 功能 查询过滤SQL实现类似 a.IsDeleted = 1 功能
</summary> </summary>
</member> </member>
<member name="M:FreeSql.DataAnnotations.TableFluent`1.DisableSyncStructure(System.Boolean)">
<summary>
禁用 CodeFirst 同步结构迁移
</summary>
</member>
<member name="P:FreeSql.DatabaseModel.DbColumnInfo.Table"> <member name="P:FreeSql.DatabaseModel.DbColumnInfo.Table">
<summary> <summary>
所属表 所属表
@ -480,6 +495,15 @@
<param name="executed">执行后,可监视执行性能</param> <param name="executed">执行后,可监视执行性能</param>
<returns></returns> <returns></returns>
</member> </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)"> <member name="M:FreeSql.IDelete`1.WithTransaction(System.Data.Common.DbTransaction)">
<summary> <summary>
指定事务对象 指定事务对象
@ -2251,6 +2275,55 @@
中间表,多对多 中间表,多对多
</summary> </summary>
</member> </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)"> <member name="M:FreeSqlGlobalExtensions.Distance(System.Drawing.Point,System.Drawing.Point)">
<summary> <summary>
测量两个经纬度的距离,返回单位:米 测量两个经纬度的距离,返回单位:米

View File

@ -147,7 +147,7 @@ namespace FreeSql {
ret = Activator.CreateInstance(type, new object[] { _masterConnectionString, _slaveConnectionString }) as IFreeSql<TMark>; ret = Activator.CreateInstance(type, new object[] { _masterConnectionString, _slaveConnectionString }) as IFreeSql<TMark>;
if (ret != null) { if (ret != null) {
ret.CodeFirst.IsAutoSyncStructure = _isAutoSyncStructure; ret.CodeFirst.IsAutoSyncStructure = _isAutoSyncStructure;
ret.CodeFirst.IsSyncStructureToLower = _isSyncStructureToLower; ret.CodeFirst.IsSyncStructureToLower = _isSyncStructureToLower;
ret.CodeFirst.IsSyncStructureToUpper = _isSyncStructureToUpper; ret.CodeFirst.IsSyncStructureToUpper = _isSyncStructureToUpper;
ret.CodeFirst.IsConfigEntityFromDbFirst = _isConfigEntityFromDbFirst; ret.CodeFirst.IsConfigEntityFromDbFirst = _isConfigEntityFromDbFirst;
@ -157,73 +157,39 @@ namespace FreeSql {
ado.AopCommandExecuting += _aopCommandExecuting; ado.AopCommandExecuting += _aopCommandExecuting;
ado.AopCommandExecuted += _aopCommandExecuted; ado.AopCommandExecuted += _aopCommandExecuted;
//添加实体属性名全局AOP转换处理 //添加实体属性名全局AOP转换处理
if (_entityPropertyConvertType != StringConvertType.None) if (_entityPropertyConvertType != StringConvertType.None) {
{ switch (_entityPropertyConvertType) {
// 局部方法判断是否存在Column特性以及是否设置Name的值 case StringConvertType.Lower:
bool CheckEntityPropertyColumnAttribute(PropertyInfo propertyInfo) ret.Aop.ConfigEntityProperty = (s, e) => {
{ e.ModifyResult.Name = e.Property.Name.ToLower();
var attr = propertyInfo.GetCustomAttribute<ColumnAttribute>(); };
if (attr == null || string.IsNullOrEmpty(attr.Name)) break;
{ case StringConvertType.Upper:
return true; ret.Aop.ConfigEntityProperty = (s, e) => {
} e.ModifyResult.Name = e.Property.Name.ToUpper();
};
return false; break;
} case StringConvertType.PascalCaseToUnderscore:
ret.Aop.ConfigEntityProperty = (s, e) => {
switch (_entityPropertyConvertType) e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name);
{ };
case StringConvertType.Lower: break;
ret.Aop.ConfigEntityProperty = (s, e) => case StringConvertType.PascalCaseToUnderscoreWithLower:
{ ret.Aop.ConfigEntityProperty = (s, e) => {
if (CheckEntityPropertyColumnAttribute(e.Property)) e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToLower();
{ };
e.ModifyResult.Name = e.Property.Name.ToLower(); break;
} case StringConvertType.PascalCaseToUnderscoreWithUpper:
}; ret.Aop.ConfigEntityProperty = (s, e) => {
break; e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToUpper();
case StringConvertType.Upper: };
ret.Aop.ConfigEntityProperty = (s, e) => break;
{ default:
if (CheckEntityPropertyColumnAttribute(e.Property)) break;
{ }
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;
}
}
}
return ret; return ret;
} }

View File

@ -45,9 +45,9 @@ namespace FreeSql.Internal.CommonProvider {
internal ConcurrentDictionary<string, bool> dicSyced = new ConcurrentDictionary<string, bool>(); internal ConcurrentDictionary<string, bool> dicSyced = new ConcurrentDictionary<string, bool>();
public bool SyncStructure<TEntity>() => this.SyncStructure(typeof(TEntity)); public bool SyncStructure<TEntity>() => this.SyncStructure(typeof(TEntity));
public bool SyncStructure(params Type[] entityTypes) { public bool SyncStructure(params Type[] entityTypes) {
if (entityTypes == null) return true; if (entityTypes == null) return false;
var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false).ToArray(); var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false && GetTableByEntity(a)?.DisableSyncStructure == false).ToArray();
if (syncTypes.Any() == false) return true; if (syncTypes.Any() == false) return false;
var before = new Aop.SyncStructureBeforeEventArgs(entityTypes); var before = new Aop.SyncStructureBeforeEventArgs(entityTypes);
_orm.Aop.SyncStructureBefore?.Invoke(this, before); _orm.Aop.SyncStructureBefore?.Invoke(this, before);
Exception exception = null; 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.Name)) attr.Name = trytb.Name;
if (!string.IsNullOrEmpty(trytb.OldName)) attr.OldName = trytb.OldName; if (!string.IsNullOrEmpty(trytb.OldName)) attr.OldName = trytb.OldName;
if (!string.IsNullOrEmpty(trytb.SelectFilter)) attr.SelectFilter = trytb.SelectFilter; if (!string.IsNullOrEmpty(trytb.SelectFilter)) attr.SelectFilter = trytb.SelectFilter;
if (trytb._DisableSyncStructure != null) attr._DisableSyncStructure = trytb.DisableSyncStructure;
} }
var attrs = type.GetCustomAttributes(typeof(TableAttribute), false); var attrs = type.GetCustomAttributes(typeof(TableAttribute), false);
foreach (var tryattrobj in attrs) { 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.Name)) attr.Name = tryattr.Name;
if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName; if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName;
if (!string.IsNullOrEmpty(tryattr.SelectFilter)) attr.SelectFilter = tryattr.SelectFilter; 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.Name)) return attr;
if (!string.IsNullOrEmpty(attr.OldName)) return attr; if (!string.IsNullOrEmpty(attr.OldName)) return attr;
if (!string.IsNullOrEmpty(attr.SelectFilter)) return attr; if (!string.IsNullOrEmpty(attr.SelectFilter)) return attr;
if (attr._DisableSyncStructure != null) return attr;
return null; return null;
} }
public ColumnAttribute GetEntityColumnAttribute(Type type, PropertyInfo proto) { public ColumnAttribute GetEntityColumnAttribute(Type type, PropertyInfo proto) {

View File

@ -18,6 +18,7 @@ namespace FreeSql.Internal.Model {
public string DbName { get; set; } public string DbName { get; set; }
public string DbOldName { get; set; } public string DbOldName { get; set; }
public string SelectFilter { get; set; } public string SelectFilter { get; set; }
public bool DisableSyncStructure { get; set; }
public ColumnInfo VersionColumn { get; set; } public ColumnInfo VersionColumn { get; set; }

View File

@ -53,6 +53,7 @@ namespace FreeSql.Internal {
trytb.DbOldName = trytb.DbOldName?.ToUpper(); trytb.DbOldName = trytb.DbOldName?.ToUpper();
} }
trytb.SelectFilter = tbattr?.SelectFilter; trytb.SelectFilter = tbattr?.SelectFilter;
if (tbattr != null) trytb.DisableSyncStructure = tbattr.DisableSyncStructure;
var propsLazy = new List<(PropertyInfo, bool, bool)>(); var propsLazy = new List<(PropertyInfo, bool, bool)>();
var propsNavObjs = new List<PropertyInfo>(); var propsNavObjs = new List<PropertyInfo>();
foreach (var p in trytb.Properties.Values) { foreach (var p in trytb.Properties.Values) {

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net452</TargetFrameworks> <TargetFrameworks>netstandard2.0;net452</TargetFrameworks>
<Version>0.6.9</Version> <Version>0.6.10</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors> <Authors>YeXiangQin</Authors>
<Description>FreeSql 数据库实现,基于 MySql 5.6</Description> <Description>FreeSql 数据库实现,基于 MySql 5.6</Description>

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks> <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.6.9</Version> <Version>0.6.10</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors> <Authors>YeXiangQin</Authors>
<Description>FreeSql 数据库实现,基于 MySql 5.6</Description> <Description>FreeSql 数据库实现,基于 MySql 5.6</Description>

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks> <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.6.9</Version> <Version>0.6.10</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors> <Authors>YeXiangQin</Authors>
<Description>FreeSql 数据库实现,基于 Oracle 11</Description> <Description>FreeSql 数据库实现,基于 Oracle 11</Description>

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks> <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.6.9</Version> <Version>0.6.10</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors> <Authors>YeXiangQin</Authors>
<Description>FreeSql 数据库实现,基于 PostgreSQL 9.5</Description> <Description>FreeSql 数据库实现,基于 PostgreSQL 9.5</Description>

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net451</TargetFrameworks> <TargetFrameworks>netstandard2.0;net451</TargetFrameworks>
<Version>0.6.9</Version> <Version>0.6.10</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors> <Authors>YeXiangQin</Authors>
<Description>FreeSql 数据库实现,基于 SqlServer 2005+并根据版本适配分页方法row_number 或 offset fetch next</Description> <Description>FreeSql 数据库实现,基于 SqlServer 2005+并根据版本适配分页方法row_number 或 offset fetch next</Description>

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks> <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.6.9</Version> <Version>0.6.10</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors> <Authors>YeXiangQin</Authors>
<Description>FreeSql 数据库实现,基于 Sqlite 3.0</Description> <Description>FreeSql 数据库实现,基于 Sqlite 3.0</Description>