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

View File

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

View File

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

View File

@ -129,6 +129,17 @@ namespace FreeSql
/// <param name="data"></param>
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);
/// <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
#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>

View File

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

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

View File

@ -140,6 +140,11 @@ namespace FreeSql
public void Attach(TEntity data) => _db.Attach(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 TEntity InsertOrUpdate(TEntity entity)

View File

@ -21,6 +21,12 @@ namespace FreeSql
/// <param name="entity"></param>
void Attach(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(IEnumerable<TEntity> entitys);
Task<int> UpdateAsync(TEntity entity);

View File

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

View File

@ -37,9 +37,13 @@ namespace FreeSql.Tests
repos.Attach(item);
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));
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());
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)
{
return default(T);
return (T)Internal.Utils.GetDataReaderValue(typeof(T), that);
}
public static string FormatDateTime()
@ -407,6 +407,12 @@ namespace FreeSql.Tests
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 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();

View File

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

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

View File

@ -83,7 +83,7 @@ namespace FreeSql.MySql
if (callExp.Method.DeclaringType.IsNumberType()) return "rand()";
break;
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;
}
@ -385,7 +385,7 @@ namespace FreeSql.MySql
break;
case "Equals": return $"({left} = {getExp(exp.Arguments[0])})";
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;

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.9.15</Version>
<Version>0.9.16</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.9.15</Version>
<Version>0.9.16</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors>
<Description>FreeSql 数据库实现,基于 Oracle 11</Description>

View File

@ -83,7 +83,7 @@ namespace FreeSql.Oracle
if (callExp.Method.DeclaringType.IsNumberType()) return "dbms_random.value";
break;
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;
}
@ -387,7 +387,7 @@ namespace FreeSql.Oracle
break;
case "Equals": return $"({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;

View File

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

View File

@ -88,7 +88,7 @@ namespace FreeSql.PostgreSQL
if (callExp.Method.DeclaringType.IsNumberType()) return "random()";
break;
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;
}
@ -496,7 +496,7 @@ namespace FreeSql.PostgreSQL
break;
case "Equals": return $"({left} = ({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;

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net451</TargetFrameworks>
<Version>0.9.15</Version>
<Version>0.9.16</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors>
<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()";
break;
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;
}
@ -367,7 +367,7 @@ namespace FreeSql.SqlServer
break;
case "Equals": return $"({left} = {getExp(exp.Arguments[0])})";
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;

View File

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

View File

@ -83,7 +83,7 @@ namespace FreeSql.Sqlite
if (callExp.Method.DeclaringType.IsNumberType()) return "random()";
break;
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;
}
@ -389,7 +389,7 @@ namespace FreeSql.Sqlite
break;
case "Equals": return $"({left} = {getExp(exp.Arguments[0])})";
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;