修正命名 NaviteTuple 为 NativeTuple

This commit is contained in:
28810
2020-08-02 13:38:23 +08:00
parent 688f754036
commit 552926dd96
41 changed files with 407 additions and 336 deletions

View File

@ -78,19 +78,19 @@ namespace FreeSql
protected virtual void OnModelCreating(ICodeFirst codefirst) { }
#region Set
static ConcurrentDictionary<Type, NaviteTuple<PropertyInfo[], bool>> _dicGetDbSetProps = new ConcurrentDictionary<Type, NaviteTuple<PropertyInfo[], bool>>();
static ConcurrentDictionary<Type, NativeTuple<PropertyInfo[], bool>> _dicGetDbSetProps = new ConcurrentDictionary<Type, NativeTuple<PropertyInfo[], bool>>();
internal void InitPropSets()
{
var thisType = this.GetType();
var dicval = _dicGetDbSetProps.GetOrAdd(thisType, tp =>
NaviteTuple.Create(
NativeTuple.Create(
tp.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)
.Where(a => a.PropertyType.IsGenericType &&
a.PropertyType == typeof(DbSet<>).MakeGenericType(a.PropertyType.GetGenericArguments()[0])).ToArray(),
false));
if (dicval.Item2 == false)
{
if (_dicGetDbSetProps.TryUpdate(thisType, NaviteTuple.Create(dicval.Item1, true), dicval))
if (_dicGetDbSetProps.TryUpdate(thisType, NativeTuple.Create(dicval.Item1, true), dicval))
OnModelCreating(OrmOriginal.CodeFirst);
}

View File

@ -1,12 +1,13 @@
using FreeSql.Extensions.EntityUtil;
using FreeSql.Internal.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Linq.Expressions;
namespace FreeSql
{
@ -539,82 +540,85 @@ namespace FreeSql
/// 开始编辑数据,然后调用方法 EndEdit 分析出添加、修改、删除 SQL 语句进行执行<para></para>
/// 场景winform 加载表数据后,一顿添加、修改、删除操作之后,最后才点击【保存】<para></para><para></para>
/// 示例https://github.com/dotnetcore/FreeSql/issues/397<para></para>
/// 注意:* 本方法只支持单表操作,不支持导航属性级联保存
/// </summary>
/// <param name="data"></param>
//public void BeginEdit(List<TEntity> data)
//{
// if (data == null || data.Any() == false) return;
// if (_table.Primarys.Any() == false) throw new Exception($"不可进行编辑,实体没有主键:{_db.OrmOriginal.GetEntityString(_entityType, data.First())}");
// _statesEditing.Clear();
// _dataEditing = data;
// foreach (var item in data)
// {
// var key = _db.OrmOriginal.GetEntityKeyString(_entityType, item, false);
// if (string.IsNullOrEmpty(key)) continue;
public void BeginEdit(List<TEntity> data)
{
if (data == null || data.Any() == false) return;
if (_table.Primarys.Any() == false) throw new Exception($"不可进行编辑,实体没有主键:{_db.OrmOriginal.GetEntityString(_entityType, data.First())}");
_statesEditing.Clear();
_dataEditing = data;
foreach (var item in data)
{
var key = _db.OrmOriginal.GetEntityKeyString(_entityType, item, false);
if (string.IsNullOrEmpty(key)) continue;
// _statesEditing.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) =>
// {
// _db.OrmOriginal.MapEntityValue(_entityType, item, ov.Value);
// ov.Time = DateTime.Now;
// return ov;
// });
// }
//}
///// <summary>
///// 完成编辑数据,进行保存动作<para></para>
///// 该方法根据 BeginEdit 传入的状态分析出添加、修改、删除 SQL 语句
///// </summary>
///// <returns></returns>
//public int EndEdit()
//{
// var beforeAffrows = 0;
// if (_dataEditing == null) return 0;
// var oldEnable = _db.Options.EnableAddOrUpdateNavigateList;
// _db.Options.EnableAddOrUpdateNavigateList = false;
// try
// {
// DbContextFlushCommand();
// var addList = new List<TEntity>();
// var ediList = new List<TEntity>();
// foreach (var item in _dataEditing)
// {
// var key = _db.OrmOriginal.GetEntityKeyString(_entityType, item, false);
// if (_statesEditing.TryRemove(key, out var state) == false)
// {
// addList.Add(item);
// continue;
// }
// _states.AddOrUpdate(key, k => state, (k, ov) =>
// {
// ov.Value = state.Value;
// ov.Time = DateTime.Now;
// return ov;
// });
// if (_db.OrmOriginal.CompareEntityValueReturnColumns(_entityType, item, state.Value, false).Any())
// ediList.Add(item);
// }
// beforeAffrows = _db._affrows;
// AddRange(addList);
// UpdateRange(ediList);
_statesEditing.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) =>
{
_db.OrmOriginal.MapEntityValue(_entityType, item, ov.Value);
ov.Time = DateTime.Now;
return ov;
});
}
}
/// <summary>
/// 完成编辑数据,进行保存动作<para></para>
/// 该方法根据 BeginEdit 传入的数据状态分析出添加、修改、删除 SQL 语句<para></para>
/// 注意:* 本方法只支持单表操作,不支持导航属性级联保存
/// </summary>
/// <returns></returns>
public int EndEdit()
{
var beforeAffrows = 0;
if (_dataEditing == null) return 0;
var oldEnable = _db.Options.EnableAddOrUpdateNavigateList;
_db.Options.EnableAddOrUpdateNavigateList = false;
try
{
DbContextFlushCommand();
var addList = new List<TEntity>();
var ediList = new List<NativeTuple<TEntity, string>>();
foreach (var item in _dataEditing)
{
var key = _db.OrmOriginal.GetEntityKeyString(_entityType, item, false);
if (_statesEditing.TryRemove(key, out var state) == false)
{
addList.Add(item);
continue;
}
_states.AddOrUpdate(key, k => state, (k, ov) =>
{
ov.Value = state.Value;
ov.Time = DateTime.Now;
return ov;
});
var edicmp = _db.OrmOriginal.CompareEntityValueReturnColumns(_entityType, item, state.Value, false);
if (edicmp.Any())
ediList.Add(NativeTuple.Create(item, string.Join(",", edicmp)));
}
beforeAffrows = _db._affrows;
AddRange(addList);
UpdateRange(ediList.OrderBy(a => a.Item2).Select(a => a.Item1).ToList());
// DbContextFlushCommand();
// var delList = _statesEditing.Values.OrderBy(a => a.Time).ToArray();
// _db._affrows += DbContextBatchRemove(delList); //为了减的少不必要的开销,此处没有直接调用 RemoveRange
// foreach (var state in delList)
// {
// _db.OrmOriginal.ClearEntityPrimaryValueWithIdentityAndGuid(_entityType, state.Value);
// _states.TryRemove(state.Key, out var oldstate);
// }
// DbContextFlushCommand();
// }
// finally
// {
// _dataEditing = null;
// _statesEditing.Clear();
// _db.Options.EnableAddOrUpdateNavigateList = oldEnable;
// }
// return _db._affrows - beforeAffrows;
//}
DbContextFlushCommand();
var delList = _statesEditing.Values.OrderBy(a => a.Time).ToArray();
_db._affrows += DbContextBatchRemove(delList); //为了减的少不必要的开销,此处没有直接调用 RemoveRange
foreach (var state in delList)
{
_db.OrmOriginal.ClearEntityPrimaryValueWithIdentityAndGuid(_entityType, state.Value);
_states.TryRemove(state.Key, out var oldstate);
}
DbContextFlushCommand();
}
finally
{
_dataEditing = null;
_statesEditing.Clear();
_db.Options.EnableAddOrUpdateNavigateList = oldEnable;
}
return _db._affrows - beforeAffrows;
}
#endregion
}
}

View File

@ -125,13 +125,6 @@
清空状态数据
</summary>
</member>
<member name="M:FreeSql.DbSet`1.RemoveAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
<summary>
根据 lambda 条件删除数据
</summary>
<param name="predicate"></param>
<returns></returns>
</member>
<member name="M:FreeSql.DbSet`1.Add(`0)">
<summary>
添加
@ -174,6 +167,23 @@
</summary>
<param name="data"></param>
</member>
<member name="M:FreeSql.DbSet`1.BeginEdit(System.Collections.Generic.List{`0})">
<summary>
开始编辑数据,然后调用方法 EndEdit 分析出添加、修改、删除 SQL 语句进行执行<para></para>
场景winform 加载表数据后,一顿添加、修改、删除操作之后,最后才点击【保存】<para></para><para></para>
示例https://github.com/dotnetcore/FreeSql/issues/397<para></para>
注意:* 本方法只支持单表操作,不支持导航属性级联保存
</summary>
<param name="data"></param>
</member>
<member name="M:FreeSql.DbSet`1.EndEdit">
<summary>
完成编辑数据,进行保存动作<para></para>
该方法根据 BeginEdit 传入的数据状态分析出添加、修改、删除 SQL 语句<para></para>
注意:* 本方法只支持单表操作,不支持导航属性级联保存
</summary>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.EfCoreFluentApi.EfCoreColumnFluent.Help">
<summary>
使用 FreeSql FluentApi 方法,当 EFCore FluentApi 方法无法表示的时候使用
@ -304,6 +314,23 @@
<param name="entity">实体对象</param>
<param name="propertyName">属性名</param>
</member>
<member name="M:FreeSql.IBaseRepository`1.BeginEdit(System.Collections.Generic.List{`0})">
<summary>
开始编辑数据,然后调用方法 EndEdit 分析出添加、修改、删除 SQL 语句进行执行<para></para>
场景winform 加载表数据后,一顿添加、修改、删除操作之后,最后才点击【保存】<para></para><para></para>
示例https://github.com/dotnetcore/FreeSql/issues/397<para></para>
注意:* 本方法只支持单表操作,不支持导航属性级联保存
</summary>
<param name="data"></param>
</member>
<member name="M:FreeSql.IBaseRepository`1.EndEdit">
<summary>
完成编辑数据,进行保存动作<para></para>
该方法根据 BeginEdit 传入的数据状态分析出添加、修改、删除 SQL 语句<para></para>
注意:* 本方法只支持单表操作,不支持导航属性级联保存
</summary>
<returns></returns>
</member>
<member name="T:FreeSql.IUnitOfWork">
<summary>
工作单元
@ -486,14 +513,5 @@
<param name="that"></param>
<returns></returns>
</member>
<member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
<summary>
批量注入 Repository可以参考代码自行调整
</summary>
<param name="services"></param>
<param name="globalDataFilter"></param>
<param name="assemblies"></param>
<returns></returns>
</member>
</members>
</doc>

View File

@ -119,11 +119,11 @@ namespace FreeSql
return _db.SaveChanges();
}
public void Attach(TEntity data) => _db.Attach(data);
public void Attach(IEnumerable<TEntity> data) => _db.AttachRange(data);
public void Attach(TEntity data) => _dbset.Attach(data);
public void Attach(IEnumerable<TEntity> data) => _dbset.AttachRange(data);
public IBaseRepository<TEntity> AttachOnlyPrimary(TEntity data)
{
_db.AttachOnlyPrimary(data);
_dbset.AttachOnlyPrimary(data);
return this;
}
public void FlushState() => _dbset.FlushState();
@ -140,6 +140,9 @@ namespace FreeSql
_dbset.SaveMany(entity, propertyName);
_db.SaveChanges();
}
public void BeginEdit(List<TEntity> data) => _dbset.BeginEdit(data);
public int EndEdit() => _dbset.EndEdit();
}
public abstract partial class BaseRepository<TEntity, TKey> : BaseRepository<TEntity>, IBaseRepository<TEntity, TKey>

View File

@ -79,6 +79,22 @@ namespace FreeSql
int Delete(IEnumerable<TEntity> entitys);
int Delete(Expression<Func<TEntity, bool>> predicate);
/// <summary>
/// 开始编辑数据,然后调用方法 EndEdit 分析出添加、修改、删除 SQL 语句进行执行<para></para>
/// 场景winform 加载表数据后,一顿添加、修改、删除操作之后,最后才点击【保存】<para></para><para></para>
/// 示例https://github.com/dotnetcore/FreeSql/issues/397<para></para>
/// 注意:* 本方法只支持单表操作,不支持导航属性级联保存
/// </summary>
/// <param name="data"></param>
void BeginEdit(List<TEntity> data);
/// <summary>
/// 完成编辑数据,进行保存动作<para></para>
/// 该方法根据 BeginEdit 传入的数据状态分析出添加、修改、删除 SQL 语句<para></para>
/// 注意:* 本方法只支持单表操作,不支持导航属性级联保存
/// </summary>
/// <returns></returns>
int EndEdit();
#if net40
#else
Task<TEntity> InsertAsync(TEntity entity);