## v0.9.16

- 增加 BaseRepository.AttachOnlyPrimary 方法,只附加实体的主键值;
> 在更新前使用可实现不查询数据库再更新、也可以实现更新时不更新值为 null 的字段
```csharp
class T {
    public int id { get; set; }
    public string name { get; set; }
    public string other { get; set; }
}
var item = new T { id = 1, name = "xx" };
fsql.GetRepository<T>().AttachOnlyPrimary(item).Update(item); //只更新 name
```
- 修复 Lambda 表达式中 DateTime.Now.ToString("yyyyMMdd") 不能直接执行的 bug;
This commit is contained in:
28810 2019-09-18 16:58:13 +08:00
parent 52450dc08a
commit 8d92ccd751
24 changed files with 92 additions and 24 deletions

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks> <TargetFrameworks>netstandard2.0</TargetFrameworks>
<Version>0.9.15</Version> <Version>0.9.16</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors> <Authors>YeXiangQin</Authors>
<Description>BaseEntity 是一种极简单的 CodeFirst 开发方式特别对单表或多表CRUD利用继承节省了每个实体类的重复属性创建时间、ID等字段软件删除等功能进行 crud 操作时不必时常考虑仓储的使用.</Description> <Description>BaseEntity 是一种极简单的 CodeFirst 开发方式特别对单表或多表CRUD利用继承节省了每个实体类的重复属性创建时间、ID等字段软件删除等功能进行 crud 操作时不必时常考虑仓储的使用.</Description>

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks> <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.9.15</Version> <Version>0.9.16</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors> <Authors>YeXiangQin</Authors>
<Description>FreeSql 扩展包可实现实体类属性为对象时以JSON形式映射存储.</Description> <Description>FreeSql 扩展包可实现实体类属性为对象时以JSON形式映射存储.</Description>

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks> <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.9.15</Version> <Version>0.9.16</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors> <Authors>YeXiangQin</Authors>
<Description>FreeSql 扩展包,可实现【延时加载】属性.</Description> <Description>FreeSql 扩展包,可实现【延时加载】属性.</Description>

View File

@ -129,6 +129,17 @@ namespace FreeSql
/// <param name="data"></param> /// <param name="data"></param>
public void Attach<TEntity>(TEntity data) where TEntity : class => this.Set<TEntity>().Attach(data); public void Attach<TEntity>(TEntity data) where TEntity : class => this.Set<TEntity>().Attach(data);
public void AttachRange<TEntity>(IEnumerable<TEntity> data) where TEntity : class => this.Set<TEntity>().AttachRange(data); public void AttachRange<TEntity>(IEnumerable<TEntity> data) where TEntity : class => this.Set<TEntity>().AttachRange(data);
/// <summary>
/// 附加实体并且只附加主键值可用于不更新属性值为null或默认值的字段
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="data"></param>
public DbContext AttachOnlyPrimary<TEntity>(TEntity data) where TEntity : class
{
this.Set<TEntity>().AttachOnlyPrimary(data);
return this;
}
#endregion #endregion
#region Queue Action #region Queue Action

View File

@ -162,6 +162,23 @@ namespace FreeSql
}); });
} }
} }
/// <summary>
/// 附加实体并且只附加主键值可用于不更新属性值为null或默认值的字段
/// </summary>
/// <param name="data"></param>
public DbSet<TEntity> AttachOnlyPrimary(TEntity data)
{
if (data == null) return this;
var pkitem = (TEntity)Activator.CreateInstance(_entityType);
foreach (var pk in _db.Orm.CodeFirst.GetTableByEntity(_entityType).Primarys)
{
var colVal = _db.Orm.GetEntityValueWithPropertyName(_entityType, data, pk.CsName);
_db.Orm.SetEntityValueWithPropertyName(_entityType, pkitem, pk.CsName, colVal);
}
this.Attach(pkitem);
return this;
}
/// <summary> /// <summary>
/// 清空状态数据 /// 清空状态数据
/// </summary> /// </summary>

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks> <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.9.15</Version> <Version>0.9.16</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

@ -39,6 +39,13 @@
<typeparam name="TEntity"></typeparam> <typeparam name="TEntity"></typeparam>
<param name="data"></param> <param name="data"></param>
</member> </member>
<member name="M:FreeSql.DbContext.AttachOnlyPrimary``1(``0)">
<summary>
附加实体并且只附加主键值可用于不更新属性值为null或默认值的字段
</summary>
<typeparam name="TEntity"></typeparam>
<param name="data"></param>
</member>
<member name="P:FreeSql.DbContextOptions.EnableAddOrUpdateNavigateList"> <member name="P:FreeSql.DbContextOptions.EnableAddOrUpdateNavigateList">
<summary> <summary>
是否开启一对多,联级保存功能 是否开启一对多,联级保存功能
@ -57,6 +64,12 @@
</summary> </summary>
<param name="data"></param> <param name="data"></param>
</member> </member>
<member name="M:FreeSql.DbSet`1.AttachOnlyPrimary(`0)">
<summary>
附加实体并且只附加主键值可用于不更新属性值为null或默认值的字段
</summary>
<param name="data"></param>
</member>
<member name="M:FreeSql.DbSet`1.FlushState"> <member name="M:FreeSql.DbSet`1.FlushState">
<summary> <summary>
清空状态数据 清空状态数据
@ -156,6 +169,12 @@
</summary> </summary>
<param name="entity"></param> <param name="entity"></param>
</member> </member>
<member name="M:FreeSql.IBasicRepository`1.AttachOnlyPrimary(`0)">
<summary>
附加实体并且只附加主键值可用于不更新属性值为null或默认值的字段
</summary>
<param name="data"></param>
</member>
<member name="P:FreeSql.IUnitOfWork.Enable"> <member name="P:FreeSql.IUnitOfWork.Enable">
<summary> <summary>
是否启用工作单元 是否启用工作单元

View File

@ -140,6 +140,11 @@ namespace FreeSql
public void Attach(TEntity data) => _db.Attach(data); public void Attach(TEntity data) => _db.Attach(data);
public void Attach(IEnumerable<TEntity> data) => _db.AttachRange(data); public void Attach(IEnumerable<TEntity> data) => _db.AttachRange(data);
public IBasicRepository<TEntity> AttachOnlyPrimary(TEntity data)
{
_db.AttachOnlyPrimary(data);
return this;
}
public void FlushState() => _dbset.FlushState(); public void FlushState() => _dbset.FlushState();
public TEntity InsertOrUpdate(TEntity entity) public TEntity InsertOrUpdate(TEntity entity)

View File

@ -21,6 +21,12 @@ namespace FreeSql
/// <param name="entity"></param> /// <param name="entity"></param>
void Attach(TEntity entity); void Attach(TEntity entity);
void Attach(IEnumerable<TEntity> entity); void Attach(IEnumerable<TEntity> entity);
/// <summary>
/// 附加实体并且只附加主键值可用于不更新属性值为null或默认值的字段
/// </summary>
/// <param name="data"></param>
IBasicRepository<TEntity> AttachOnlyPrimary(TEntity data);
int Update(TEntity entity); int Update(TEntity entity);
int Update(IEnumerable<TEntity> entitys); int Update(IEnumerable<TEntity> entitys);
Task<int> UpdateAsync(TEntity entity); Task<int> UpdateAsync(TEntity entity);

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks> <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.9.15</Version> <Version>0.9.16</Version>
<Authors>YeXiangQin</Authors> <Authors>YeXiangQin</Authors>
<Description>FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table.</Description> <Description>FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table.</Description>
<PackageProjectUrl>https://github.com/2881099/FreeSql/wiki/Repository</PackageProjectUrl> <PackageProjectUrl>https://github.com/2881099/FreeSql/wiki/Repository</PackageProjectUrl>

View File

@ -37,9 +37,13 @@ namespace FreeSql.Tests
repos.Attach(item); repos.Attach(item);
item.Title = "xxx"; item.Title = "xxx";
repos.Update(item); repos.Update(item); //这行执行 UPDATE "AddUpdateInfo" SET "Title" = 'xxx' WHERE("Id" = '1942fb53-9700-411d-8895-ce4cecdf3257')
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item));
repos.Update(item); //这行不执行 SQL未变化
repos.AttachOnlyPrimary(item).Update(item); //这行更新状态值,只有主键值存在,执行更新 set title = xxx
Console.WriteLine(repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ToSql()); Console.WriteLine(repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ToSql());
repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ExecuteAffrows(); repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ExecuteAffrows();

View File

@ -22,7 +22,7 @@ namespace FreeSql.Tests
{ {
public static T TryTo<T>(this string that) public static T TryTo<T>(this string that)
{ {
return default(T); return (T)Internal.Utils.GetDataReaderValue(typeof(T), that);
} }
public static string FormatDateTime() public static string FormatDateTime()
@ -407,6 +407,12 @@ namespace FreeSql.Tests
public void Test1() public void Test1()
{ {
var testrunsql1 = g.mysql.Select<TaskBuild>().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo<int>()).ToSql();
var testrunsql2 = g.pgsql.Select<TaskBuild>().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo<int>()).ToSql();
var testrunsql3 = g.sqlserver.Select<TaskBuild>().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo<int>()).ToSql();
var testrunsql4 = g.oracle.Select<TaskBuild>().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo<int>()).ToSql();
var testrunsql5 = g.sqlite.Select<TaskBuild>().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo<int>()).ToSql();
var testssargs1 = "10100"; var testssargs1 = "10100";
var testformatsql1 = g.mysql.Select<TaskBuild>().Where(a => a.NamespaceName == $"1_{10100}").ToSql(); var testformatsql1 = g.mysql.Select<TaskBuild>().Where(a => a.NamespaceName == $"1_{10100}").ToSql();
var testorderbysql = g.mysql.Select<TaskBuild>().OrderByDescending(a => a.OptionsEntity04 + (a.score ?? 0)).ToSql(); var testorderbysql = g.mysql.Select<TaskBuild>().OrderByDescending(a => a.OptionsEntity04 + (a.score ?? 0)).ToSql();

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks> <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.9.15</Version> <Version>0.9.16</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

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net452</TargetFrameworks> <TargetFrameworks>netstandard2.0;net452</TargetFrameworks>
<Version>0.9.15</Version> <Version>0.9.16</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

@ -83,7 +83,7 @@ namespace FreeSql.MySql
if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; if (callExp.Method.DeclaringType.IsNumberType()) return "rand()";
break; break;
case "ToString": case "ToString":
if (callExp.Object != null) return $"cast({getExp(callExp.Object)} as char)"; if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"cast({getExp(callExp.Object)} as char)" : null;
break; break;
} }
@ -385,7 +385,7 @@ namespace FreeSql.MySql
break; break;
case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; case "Equals": return $"({left} = {getExp(exp.Arguments[0])})";
case "CompareTo": return $"timestampdiff(microsecond,{args1},{left})"; case "CompareTo": return $"timestampdiff(microsecond,{args1},{left})";
case "ToString": return $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')"; case "ToString": return exp.Arguments.Count == 0 ? $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')" : null;
} }
} }
return null; return null;

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks> <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.9.15</Version> <Version>0.9.16</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.9.15</Version> <Version>0.9.16</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

@ -83,7 +83,7 @@ namespace FreeSql.Oracle
if (callExp.Method.DeclaringType.IsNumberType()) return "dbms_random.value"; if (callExp.Method.DeclaringType.IsNumberType()) return "dbms_random.value";
break; break;
case "ToString": case "ToString":
if (callExp.Object != null) return $"to_char({getExp(callExp.Object)})"; if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"to_char({getExp(callExp.Object)})" : null;
break; break;
} }
@ -387,7 +387,7 @@ namespace FreeSql.Oracle
break; break;
case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; case "Equals": return $"({left} = {getExp(exp.Arguments[0])})";
case "CompareTo": return $"extract(day from ({left}-({getExp(exp.Arguments[0])})))"; case "CompareTo": return $"extract(day from ({left}-({getExp(exp.Arguments[0])})))";
case "ToString": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')" : null;
} }
} }
return null; return null;

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks> <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.9.15</Version> <Version>0.9.16</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

@ -88,7 +88,7 @@ namespace FreeSql.PostgreSQL
if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; if (callExp.Method.DeclaringType.IsNumberType()) return "random()";
break; break;
case "ToString": case "ToString":
if (callExp.Object != null) return $"({getExp(callExp.Object)})::varchar"; if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::varchar" : null;
break; break;
} }
@ -496,7 +496,7 @@ namespace FreeSql.PostgreSQL
break; break;
case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::timestamp)"; case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::timestamp)";
case "CompareTo": return $"extract(epoch from ({left})::timestamp-({getExp(exp.Arguments[0])})::timestamp)"; case "CompareTo": return $"extract(epoch from ({left})::timestamp-({getExp(exp.Arguments[0])})::timestamp)";
case "ToString": return $"to_char({left}, 'YYYY-MM-DD HH24:MI:SS.US')"; case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left}, 'YYYY-MM-DD HH24:MI:SS.US')" : null;
} }
} }
return null; return null;

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net451</TargetFrameworks> <TargetFrameworks>netstandard2.0;net451</TargetFrameworks>
<Version>0.9.15</Version> <Version>0.9.16</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

@ -87,7 +87,7 @@ namespace FreeSql.SqlServer
if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; if (callExp.Method.DeclaringType.IsNumberType()) return "rand()";
break; break;
case "ToString": case "ToString":
if (callExp.Object != null) return callExp.Object.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(callExp.Object)} as varchar(36))" : $"cast({getExp(callExp.Object)} as nvarchar)"; if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (callExp.Object.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(callExp.Object)} as varchar(36))" : $"cast({getExp(callExp.Object)} as nvarchar)") : null;
break; break;
} }
@ -367,7 +367,7 @@ namespace FreeSql.SqlServer
break; break;
case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; case "Equals": return $"({left} = {getExp(exp.Arguments[0])})";
case "CompareTo": return $"datediff(second,{getExp(exp.Arguments[0])},{left})"; case "CompareTo": return $"datediff(second,{getExp(exp.Arguments[0])},{left})";
case "ToString": return $"convert(varchar, {left}, 121)"; case "ToString": return exp.Arguments.Count == 0 ? $"convert(varchar, {left}, 121)" : null;
} }
} }
return null; return null;

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks> <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.9.15</Version> <Version>0.9.16</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>

View File

@ -83,7 +83,7 @@ namespace FreeSql.Sqlite
if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; if (callExp.Method.DeclaringType.IsNumberType()) return "random()";
break; break;
case "ToString": case "ToString":
if (callExp.Object != null) return $"cast({getExp(callExp.Object)} as character)"; if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"cast({getExp(callExp.Object)} as character)" : null;
break; break;
} }
@ -389,7 +389,7 @@ namespace FreeSql.Sqlite
break; break;
case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; case "Equals": return $"({left} = {getExp(exp.Arguments[0])})";
case "CompareTo": return $"(strftime('%s',{left})-strftime('%s',{args1}))"; case "CompareTo": return $"(strftime('%s',{left})-strftime('%s',{args1}))";
case "ToString": return $"strftime('%Y-%m-%d %H:%M.%f',{left})"; case "ToString": return exp.Arguments.Count == 0 ? $"strftime('%Y-%m-%d %H:%M.%f',{left})" : null;
} }
} }
return null; return null;