mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-06-18 20:08:15 +08:00
修正命名 NaviteTuple 为 NativeTuple
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user