TemplateData;
///
/// 要导入的Model列表
///
[JsonIgnore]
public List EntityList { get; set; }
///
/// 模版
///
[JsonIgnore]
public T Template { get; set; }
///
/// Model数据是否已被赋值
///
protected bool isEntityListSet = false;
///
/// 声明XSSF
///
protected XSSFWorkbook xssfworkbook;
///
/// 唯一性验证
///
protected DuplicatedInfo
finalInfo;
///
/// 是否存在主子表
///
protected bool HasSubTable { get; set; }
///
/// 是否在sqlserver时使用bulk导入
///
public bool UseBulkSave { get; set; }
///
/// 是否覆盖已有数据
///
public bool IsOverWriteExistData { get; set; } = true;
#endregion
#region 构造函数
public BaseImportVM()
{
ErrorListVM = new TemplateErrorListVM();
ValidityTemplateType = true;
Template = new T();
}
#endregion
#region 生成excel
///
/// 生成模版
///
/// 模版文件名
/// 生成的模版
public virtual byte[] GenerateTemplate(out string displayName)
{
return Template.GenerateTemplate(out displayName);
}
#endregion
#region 设置参数值
///
/// 设置模版参数
///
/// 参数
public void SetParms(Dictionary parms)
{
Template.Parms = parms;
}
#endregion
#region 可重写方法
///
/// 设置数据唯一性验证,子类中如果需要数据唯一性验证,应重写此方法
///
/// 唯一性属性
public virtual DuplicatedInfo SetDuplicatedCheck()
{
return null;
}
///
/// 获取上传的结果值
///
public virtual void SetEntityList()
{
if (!isEntityListSet)
{
EntityList = new List
();
//初始化上传的模板数据
SetTemplateData();
//如果模板中有错误,直接返回
if (ErrorListVM.EntityList.Count > 0)
{
return;
}
//对EntityList赋值
SetEntityData();
//设置标识为初始化
isEntityListSet = true;
}
}
///
/// 获取上传模板中填写的数据,包含了对模板正确性的验证
///
public virtual void SetTemplateData()
{
if (TemplateData != null && TemplateData.Count > 0)
{
return;
}
try
{
TemplateData = new List();
xssfworkbook = new XSSFWorkbook();
//【CHECK】上传附件的ID为空
if (UploadFileId == null)
{
ErrorListVM.EntityList.Add(new ErrorMessage { Message = CoreProgram._localizer?["Sys.PleaseUploadTemplate"] });
return;
}
Models.IWtmFile file = null;
if (Wtm.ServiceProvider != null)
{
var fp = Wtm.ServiceProvider.GetRequiredService();
file = fp.GetFile(UploadFileId, true, DC);
}
if (file == null)
{
ErrorListVM.EntityList.Add(new ErrorMessage { Message = CoreProgram._localizer?["Sys.WrongTemplate"] });
return;
}
xssfworkbook = new XSSFWorkbook(file.DataStream);
file.DataStream.Dispose();
Template.InitExcelData();
Template.InitCustomFormat();
//【CHECK】判断是否上传的是正确的模板数据
string TemplateHiddenName = xssfworkbook.GetSheetAt(1).GetRow(0).Cells[2].ToString();
if (ValidityTemplateType && !TemplateHiddenName.Equals(typeof(T).Name))
{
ErrorListVM.EntityList.Add(new ErrorMessage { Message = CoreProgram._localizer?["Sys.WrongTemplate"] });
return;
}
//获取数据的Sheet页信息
ISheet sheet = xssfworkbook.GetSheetAt(0);
sheet.ForceFormulaRecalculation = true;
XSSFFormulaEvaluator XE = new XSSFFormulaEvaluator(xssfworkbook);
IEnumerator rows = sheet.GetRowEnumerator();
var cells = sheet.GetRow(0).Cells;
//获取模板中所有字段的属性
List ListTemplateProptetys = new List();
var ListPropetys = Template.GetType().GetFields().Where(x => x.FieldType == typeof(ExcelPropety)).ToList();
for (int i = 0; i < ListPropetys.Count(); i++)
{
ExcelPropety ep = (ExcelPropety)ListPropetys[i].GetValue(Template);
ListTemplateProptetys.Add(ep);
}
//【CHECK】验证模板的列数是否正确
var dynamicColumn = ListTemplateProptetys.Where(x => x.DataType == ColumnDataType.Dynamic).FirstOrDefault();
int columnCount = dynamicColumn == null ? ListTemplateProptetys.Count : (ListTemplateProptetys.Count + dynamicColumn.DynamicColumns.Count - 1);
if (columnCount != cells.Count)
{
ErrorListVM.EntityList.Add(new ErrorMessage { Message = CoreProgram._localizer?["Sys.WrongTemplate"] });
return;
}
//【CHECK】判断字段是否根据顺序能一对一相对应。 //是否可以去除?
int pIndex = 0;
HasSubTable = false;
for (int i = 0; i < cells.Count; i++)
{
//是否有子表
HasSubTable = ListTemplateProptetys[pIndex].SubTableType != null ? true : HasSubTable;
//if (ListTemplateProptetys[pIndex].DataType != ColumnDataType.Dynamic)
//{
// if (cells[i].ToString().Trim('*') != ListTemplateProptetys[pIndex].ColumnName)
// {
// ErrorListVM.EntityList.Add(new ErrorMessage { Message = CoreProgram._localizer?["Sys.WrongTemplate"] });
// return;
// }
// pIndex++;
//}
//else
//{
// var listDynamicColumns = ListTemplateProptetys[i].DynamicColumns;
// int dcCount = listDynamicColumns.Count;
// for (int dclIndex = 0; dclIndex < dcCount; dclIndex++)
// {
// if (cells[i].ToString().Trim('*') != listDynamicColumns[dclIndex].ColumnName)
// {
// ErrorListVM.EntityList.Add(new ErrorMessage { Message = CoreProgram._localizer?["Sys.WrongTemplate"] });
// break;
// }
// i = i + 1;
// }
// i = i - 1;
pIndex++;
//}
}
//如果有子表,则设置主表字段非必填
if (HasSubTable)
{
for (int i = 0; i < cells.Count; i++)
{
ListTemplateProptetys[i].IsNullAble = ListTemplateProptetys[i].SubTableType == null ? true : ListTemplateProptetys[i].IsNullAble;
}
}
//向TemplateData中赋值
int rowIndex = 2;
rows.MoveNext();
while (rows.MoveNext())
{
XSSFRow row = (XSSFRow)rows.Current;
if (IsEmptyRow(row, columnCount))
{
return;
}
T result = new T();
pIndex = 0;
for (int i = 0; i < columnCount; i++)
{
//获取列的值
string value = row.GetCell(i, MissingCellPolicy.CREATE_NULL_AS_BLANK).ToString();
ExcelPropety excelPropety = CopyExcelPropety(ListTemplateProptetys[pIndex]);
if (excelPropety.DataType == ColumnDataType.Text)
{
ICell cell = row.GetCell(i);
value = GetCellFormulaValue(XE, cell, value);
}
if (excelPropety.DataType == ColumnDataType.Dynamic)
{
int dynamicColCount = excelPropety.DynamicColumns.Count();
for (int dynamicColIndex = 0; dynamicColIndex < dynamicColCount; dynamicColIndex++)
{
excelPropety.DynamicColumns[dynamicColIndex].ValueValidity(row.GetCell(i + dynamicColIndex, MissingCellPolicy.CREATE_NULL_AS_BLANK).ToString(), ErrorListVM.EntityList, rowIndex);
}
i = i + dynamicColCount - 1;
}
else
{
excelPropety.ValueValidity(value, ErrorListVM.EntityList, rowIndex);
}
//如果没有错误,进行赋值
if (ErrorListVM.EntityList.Count == 0)
{
var pts = ListPropetys[pIndex];
pts.SetValue(result, excelPropety);
}
pIndex++;
}
result.ExcelIndex = rowIndex;
TemplateData.Add(result);
rowIndex++;
}
return;
}
catch
{
ErrorListVM.EntityList.Add(new ErrorMessage { Message = CoreProgram._localizer?["Sys.WrongTemplate"] });
}
}
#region 进行公式计算
public string GetCellFormulaValue(XSSFFormulaEvaluator XE, ICell cell, string Value)
{
if (!string.IsNullOrEmpty(Value) && Value.IndexOf("=") == 0)
{
try
{
string Formula = Value.Substring(1);
cell.SetCellFormula(Formula);
XE.EvaluateFormulaCell(cell);
Value = cell.NumericCellValue.ToString();
}
catch (Exception)
{
}
}
return Value;
}
#endregion
///
/// 根据模板中的数据,填写导入类的集合中
///
public virtual void SetEntityData()
{
//反射出类中所有属性字段 P是Model层定义的类
var pros = typeof(P).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
//反射出模板类中的所有属性字段 T是模板类,ExcelProperty 是自定义的Excel属性类
List ListExcelFields = typeof(T).GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).Where(x => x.FieldType == typeof(ExcelPropety)).ToList();
//循环Excel中的数据
foreach (var item in TemplateData)
{
int rowIndex = 2;
bool isMainData = false;
//主表信息
Dictionary ParentEntity = new Dictionary();
string ParentEntityValues = string.Empty;
//子表信息
Dictionary> ChildrenEntity = new Dictionary>();
Dictionary ChildrenEntityDic = new Dictionary();
//循环TemplateVM中定义的所有的列,区分出主子表
foreach (var ExcelField in ListExcelFields)
{
//获取本列的ExcelProperty的值
if (typeof(T).GetField(ExcelField.Name).GetValue(item) is ExcelPropety ep)
{
//如果是子表的字段
if (ep.SubTableType != null)
{
//保存子表字段信息稍后处理
if (!ChildrenEntity.ContainsKey(ep.SubTableType))
{
ChildrenEntity[ep.SubTableType] = new List();
}
ChildrenEntity[ep.SubTableType].Add(ExcelField);
}
else
{
//保存子表字段信息稍后处理
ParentEntity.Add(ep.FieldName, ep);
ParentEntityValues += ep.Value;
}
}
}
//子表信息是否为空
foreach (var sub in ChildrenEntity)
{
string subVal = string.Empty;
foreach (var field in sub.Value)
{
ExcelPropety ep = typeof(T).GetField(field.Name).GetValue(item) as ExcelPropety;
subVal += ep.Value;
}
ChildrenEntityDic.Add(sub.Key, subVal);
}
P entity = null;
//说明主表信息为空
if (string.IsNullOrEmpty(ParentEntityValues))
{
entity = EntityList.LastOrDefault();
}
else
{
//初始化一个新的Entity
entity = new P();
isMainData = true;
//给主表赋值
foreach (var mep in ParentEntity)
{
SetEntityFieldValue(entity, mep.Value, rowIndex, mep.Key, item);
}
}
//给子表赋值
foreach (var sub in ChildrenEntity)
{
//循环Entity的所有属性,找到List类型的字段
foreach (var pro in pros)
{
if (pro.PropertyType.IsGenericType)
{
var gtype = pro.PropertyType.GetGenericArguments()[0];
if (gtype == sub.Key)
{
//子表
var subList = entity.GetType().GetSingleProperty(pro.Name).GetValue(entity);
string fk = DC.GetFKName(pro.Name);
//如果子表不为空
if (!string.IsNullOrEmpty(ChildrenEntityDic.Where(x => x.Key == sub.Key).FirstOrDefault().Value))
{
IList list = null;
if (subList == null)
{
//初始化List
list = typeof(List<>).MakeGenericType(gtype).GetConstructor(Type.EmptyTypes).Invoke(null) as IList;
}
else
{
list = subList as IList;
}
//初始化一个SubTableType
var SubTypeEntity = gtype.GetConstructor(System.Type.EmptyTypes).Invoke(null);
//给SubTableType中和本ExcelProperty同名的字段赋值
foreach (var field in sub.Value)
{
ExcelPropety ep = typeof(T).GetField(field.Name).GetValue(item) as ExcelPropety;
SetEntityFieldValue(SubTypeEntity, ep, rowIndex, ep.FieldName, item);
}
if (string.IsNullOrEmpty(fk) == false)
{
PropertyHelper.SetPropertyValue(SubTypeEntity, fk, entity.GetID());
}
if (typeof(IBasePoco).IsAssignableFrom(SubTypeEntity.GetType()))
{
(SubTypeEntity as IBasePoco).CreateTime = DateTime.Now;
(SubTypeEntity as IBasePoco).CreateBy = LoginUserInfo?.ITCode;
}
//var context = new ValidationContext(SubTypeEntity);
//var validationResults = new List();
//TryValidateObject(SubTypeEntity, context, validationResults);
//if (validationResults.Count == 0)
//{
//将付好值得SubTableType实例添加到List中
list.Add(SubTypeEntity);
PropertyHelper.SetPropertyValue(entity, pro.Name, list);
//}
//else
//{
// ErrorListVM.EntityList.Add(new ErrorMessage { Message = validationResults.FirstOrDefault()?.ErrorMessage ?? "Error", ExcelIndex = item.ExcelIndex });
// break;
//}
}
break;
}
}
}
}
entity.ExcelIndex = item.ExcelIndex;
if (isMainData)
{
EntityList.Add(entity);
}
}
}
///
/// 进行上传中的错误验证
///
public virtual void SetValidateCheck()
{
//找到对应的BaseCRUDVM,并初始化
var vms = this.GetType().Assembly.GetExportedTypes().Where(x => x.IsSubclassOf(typeof(BaseCRUDVM))).ToList();
var vmtype = vms.Where(x => x.Name.ToLower() == typeof(P).Name.ToLower() + "vm").FirstOrDefault();
if (vmtype == null)
{
vmtype = vms.FirstOrDefault();
}
IBaseCRUDVM
vm = null;
DuplicatedInfo
dinfo = null;
if (vmtype != null)
{
vm = vmtype.GetConstructor(System.Type.EmptyTypes).Invoke(null) as IBaseCRUDVM
;
vm.CopyContext(this);
dinfo = (vm as dynamic).SetDuplicatedCheck();
}
var cinfo = this.SetDuplicatedCheck();
finalInfo = new DuplicatedInfo
{
Groups = new List>()
};
if (cinfo != null)
{
foreach (var item in cinfo?.Groups)
{
finalInfo.Groups.Add(item);
}
}
else if (dinfo != null)
{
foreach (var item in dinfo?.Groups)
{
finalInfo.Groups.Add(item);
}
}
//调用controller方法验证model
//var vmethod = Controller?.GetType().GetMethod("RedoValidation");
foreach (var entity in EntityList)
{
//try
//{
// vmethod.Invoke(Controller, new object[] { entity });
//}
//catch { }
if (vm != null)
{
vm.SetEntity(entity);
vm.ByPassBaseValidation = true;
vm.Validate();
var basevm = vm as BaseVM;
if (basevm?.MSD?.Count > 0)
{
foreach (var key in basevm.MSD.Keys)
{
foreach (var error in basevm.MSD[key])
{
ErrorListVM.EntityList.Add(new ErrorMessage { Message = error.ErrorMessage, Index = entity.ExcelIndex });
}
}
}
}
(vm as BaseVM)?.MSD.Clear();
//在本地EntityList中验证是否有重复
ValidateDuplicateData(finalInfo, entity);
}
}
protected void SetEntityFieldValue(object entity, ExcelPropety ep, int rowIndex, string fieldName, T templateVM)
{
if (ep.FormatData != null)
{
ProcessResult processResult = ep.FormatData(ep.Value, templateVM);
if (processResult != null)
{
//未添加任何处理结果
if (processResult.EntityValues.Count == 0)
{
PropertyHelper.SetPropertyValue(entity, fieldName, ep.Value, stringBasedValue: true);
}
//字段为一对一
if (processResult.EntityValues.Count == 1)
{
ep.Value = processResult.EntityValues[0].FieldValue;
if (!string.IsNullOrEmpty(processResult.EntityValues[0].ErrorMsg))
{
ErrorListVM.EntityList.Add(new ErrorMessage { Message = processResult.EntityValues[0].ErrorMsg, ExcelIndex = rowIndex, Index = rowIndex });
}
PropertyHelper.SetPropertyValue(entity, fieldName, ep.Value, stringBasedValue: true);
}
//字段为一对多
if (processResult.EntityValues.Count > 1)
{
foreach (var entityValue in processResult.EntityValues)
{
if (!string.IsNullOrEmpty(entityValue.ErrorMsg))
{
ErrorListVM.EntityList.Add(new ErrorMessage { Message = entityValue.ErrorMsg, ExcelIndex = rowIndex, Index = rowIndex });
}
PropertyHelper.SetPropertyValue(entity, entityValue.FieldName, entityValue.FieldValue, stringBasedValue: true);
}
}
}
}
else if (ep.FormatSingleData != null)
{
ep.FormatSingleData(ep.Value, templateVM, out string singleEntityValue, out string errorMsg);
if (!string.IsNullOrEmpty(errorMsg))
{
ErrorListVM.EntityList.Add(new ErrorMessage { Message = errorMsg, ExcelIndex = rowIndex, Index = rowIndex });
}
PropertyHelper.SetPropertyValue(entity, fieldName, singleEntityValue, stringBasedValue: true);
}
else
{
PropertyHelper.SetPropertyValue(entity, fieldName, ep.Value, stringBasedValue: true);
}
}
protected bool IsUpdateRecordDuplicated(DuplicatedInfo checkCondition, P entity)
{
if (checkCondition != null && checkCondition.Groups.Count > 0)
{
//生成基础Query
var baseExp = EntityList.AsQueryable();
var modelType = typeof(P);
ParameterExpression para = Expression.Parameter(modelType, "tm");
//循环所有重复字段组
foreach (var group in checkCondition.Groups)
{
List conditions = new List();
//生成一个表达式,类似于 x=>x.Id != id,这是为了当修改数据时验证重复性的时候,排除当前正在修改的数据
var idproperty = modelType.GetSingleProperty("ID");
MemberExpression idLeft = Expression.Property(para, idproperty);
ConstantExpression idRight = Expression.Constant(entity.GetID());
BinaryExpression idNotEqual = Expression.NotEqual(idLeft, idRight);
conditions.Add(idNotEqual);
List props = new List();
//在每个组中循环所有字段
foreach (var field in group.Fields)
{
Expression exp = field.GetExpression(entity, para);
if (exp != null)
{
conditions.Add(exp);
}
//将字段名保存,为后面生成错误信息作准备
props.AddRange(field.GetProperties());
}
int count = 0;
if (conditions.Count > 1)
{
//循环添加条件并生成Where语句
Expression conExp = conditions[0];
for (int i = 1; i < conditions.Count; i++)
{
conExp = Expression.And(conExp, conditions[i]);
}
MethodCallExpression whereCallExpression = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { modelType },
baseExp.Expression,
Expression.Lambda>(conExp, new ParameterExpression[] { para }));
var result = baseExp.Provider.CreateQuery(whereCallExpression);
foreach (var res in result)
{
count++;
}
}
if (count > 0)
{
return true;
}
}
}
return false;
}
protected void ValidateDuplicateData(DuplicatedInfo checkCondition, P entity)
{
if (checkCondition != null && checkCondition.Groups.Count > 0)
{
//生成基础Query
var baseExp = EntityList.AsQueryable();
var modelType = typeof(P);
ParameterExpression para = Expression.Parameter(modelType, "tm");
//循环所有重复字段组
foreach (var group in checkCondition.Groups)
{
List conditions = new List();
//生成一个表达式,类似于 x=>x.Id != id,这是为了当修改数据时验证重复性的时候,排除当前正在修改的数据
var idproperty = modelType.GetSingleProperty("ExcelIndex");
MemberExpression idLeft = Expression.Property(para, idproperty);
ConstantExpression idRight = Expression.Constant(entity.ExcelIndex);
BinaryExpression idNotEqual = Expression.NotEqual(idLeft, idRight);
conditions.Add(idNotEqual);
List props = new List();
//在每个组中循环所有字段
foreach (var field in group.Fields)
{
Expression exp = field.GetExpression(entity, para);
if (exp != null)
{
conditions.Add(exp);
}
//将字段名保存,为后面生成错误信息作准备
props.AddRange(field.GetProperties());
}
int count = 0;
if (conditions.Count > 1)
{
//循环添加条件并生成Where语句
Expression whereCallExpression = baseExp.Expression;
for (int i = 0; i < conditions.Count; i++)
{
whereCallExpression = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { modelType },
whereCallExpression,
Expression.Lambda>(conditions[i], new ParameterExpression[] { para }));
}
var result = baseExp.Provider.CreateQuery(whereCallExpression);
foreach (var res in result)
{
count++;
}
}
if (count > 0)
{
//循环拼接所有字段名
string AllName = "";
foreach (var prop in props)
{
string name = PropertyHelper.GetPropertyDisplayName(prop);
AllName += name + ",";
}
if (AllName.EndsWith(","))
{
AllName = AllName.Remove(AllName.Length - 1);
}
//如果只有一个字段重复,则拼接形成 xxx字段重复 这种提示
if (props.Count == 1)
{
ErrorListVM.EntityList.Add(new ErrorMessage { Message = CoreProgram._localizer?["Sys.DuplicateError", AllName], Index = entity.ExcelIndex });
}
//如果多个字段重复,则拼接形成 xx,yy,zz组合字段重复 这种提示
else if (props.Count > 1)
{
ErrorListVM.EntityList.Add(new ErrorMessage { Message = CoreProgram._localizer?["Sys.DuplicateGroupError", AllName], Index = entity.ExcelIndex });
}
}
}
}
}
private void TryValidateObject(object model, ValidationContext context, ICollection results)
{
var modelType = model.GetType();
foreach (var p in modelType.GetProperties())
{
var propertyValue = p.GetValue(model);
TryValidateProperty(propertyValue, context, results, p);
}
}
private void TryValidateProperty(object value, ValidationContext context, ICollection results, PropertyInfo propertyInfo = null)
{
var modelType = context.ObjectType;
if (propertyInfo == null)
{
propertyInfo = modelType.GetProperty(context.MemberName!);
}
if (propertyInfo != null)
{
var rules = propertyInfo.GetCustomAttributes(true).Where(i => i.GetType().BaseType == typeof(ValidationAttribute)).Cast();
var displayName = propertyInfo.GetPropertyDisplayName();
var memberName = propertyInfo.Name;
foreach (var rule in rules)
{
if (!rule.IsValid(value))
{
string errorMessage = "Error";
if (!string.IsNullOrEmpty(rule.ErrorMessage))
{
if (rule is RangeAttribute range)
{
if (range.Minimum != null && range.Maximum != null)
{
errorMessage = Wtm.Localizer[rule.ErrorMessage, displayName, range.Minimum, range.Maximum];
}
else if (range.Minimum != null)
{
errorMessage = Wtm.Localizer[rule.ErrorMessage, displayName, range.Minimum];
}
else if (range.Maximum != null)
{
errorMessage = Wtm.Localizer[rule.ErrorMessage, displayName, range.Maximum];
}
}
else if (rule is StringLengthAttribute sl)
{
if (sl.MaximumLength > 0 && sl.MinimumLength > 0)
{
errorMessage = Wtm.Localizer[rule.ErrorMessage, displayName, sl.MinimumLength, sl.MaximumLength];
}
else if (sl.MinimumLength > 0)
{
errorMessage = Wtm.Localizer[rule.ErrorMessage, displayName, sl.MinimumLength];
}
else if (sl.MaximumLength > 0)
{
errorMessage = Wtm.Localizer[rule.ErrorMessage, displayName, sl.MaximumLength];
}
}
else
{
errorMessage = Wtm.Localizer[rule.ErrorMessage, displayName];
}
}
results.Add(new ValidationResult(errorMessage, new string[] { memberName }));
}
}
}
}
///
/// 保存指定表中的数据
///
/// 成功返回True,失败返回False
public virtual bool BatchSaveData()
{
//删除不必要的附件
if (DeletedFileIds != null && DeletedFileIds.Count > 0 && Wtm.ServiceProvider != null)
{
var fp = Wtm.ServiceProvider.GetRequiredService();
foreach (var item in DeletedFileIds)
{
fp.DeleteFile(item.ToString(), DC.ReCreate());
}
}
//进行赋值
SetEntityList();
foreach (var entity in EntityList)
{
var context = new ValidationContext(entity);
var validationResults = new List();
TryValidateObject(entity, context, validationResults);
if (validationResults.Count > 0)
{
ErrorListVM.EntityList.Add(new ErrorMessage { Message = validationResults.FirstOrDefault()?.ErrorMessage ?? "Error", ExcelIndex = entity.ExcelIndex, Index = entity.ExcelIndex });
}
}
if (ErrorListVM.EntityList.Count > 0)
{
DoReInit();
return false;
}
//执行验证
SetValidateCheck();
if (ErrorListVM.EntityList.Count > 0)
{
DoReInit();
return false;
}
//循环数据列表
List ListAdd = new List
();
foreach (var item in EntityList)
{
//根据唯一性的设定查找数据库中是否有同样的数据
P exist = IsDuplicateData(item, finalInfo);
//如果设置了覆盖功能
if (IsOverWriteExistData)
{
if (exist != null)
{
//如果有重复数据,则进行修改
var tempPros = typeof(T).GetFields();
foreach (var pro in tempPros)
{
var excelProp = Template.GetType().GetField(pro.Name).GetValue(Template) as ExcelPropety;
var proToSet = typeof(P).GetSingleProperty(excelProp.FieldName);
if (proToSet != null)
{
var val = proToSet.GetValue(item);
PropertyHelper.SetPropertyValue(exist, excelProp.FieldName, val, stringBasedValue: true);
try
{
DC.UpdateProperty(exist, proToSet.Name);
}
catch { }
}
}
if (tempPros.Where(x => x.Name == "UpdateTime").SingleOrDefault() == null)
{
if (typeof(IBasePoco).IsAssignableFrom(exist.GetType()))
{
(exist as IBasePoco).UpdateTime = DateTime.Now;
DC.UpdateProperty(exist, "UpdateTime");
}
}
if (tempPros.Where(x => x.Name == "UpdateBy").SingleOrDefault() == null)
{
if (typeof(IBasePoco).IsAssignableFrom(exist.GetType()))
{
(exist as IBasePoco).UpdateBy = LoginUserInfo.ITCode;
DC.UpdateProperty(exist, "UpdateBy");
}
}
exist.ExcelIndex = item.ExcelIndex;
//DC.UpdateEntity(exist);
continue;
}
else
{
if (typeof(IPersistPoco).IsAssignableFrom(item.GetType()))
{
(item as IPersistPoco).IsValid = true;
}
}
}
else
{
if (exist == null)
{
if (typeof(IPersistPoco).IsAssignableFrom(item.GetType()))
{
(item as IPersistPoco).IsValid = true;
}
}
}
//进行添加操作
if (typeof(IBasePoco).IsAssignableFrom(item.GetType()))
{
(item as IBasePoco).CreateTime = DateTime.Now;
(item as IBasePoco).CreateBy = LoginUserInfo?.ITCode;
}
//如果是SqlServer数据库,而且没有主子表功能,进行Bulk插入
if (ConfigInfo.Connections.Where(x => x.Key == (CurrentCS ?? "default")).FirstOrDefault().DbType == DBTypeEnum.SqlServer && !HasSubTable && UseBulkSave == true)
{
ListAdd.Add(item);
}
else
{
DC.Set
().Add(item);
}
}
if (ErrorListVM.EntityList.Count > 0)
{
DoReInit();
return false;
}
//如果没有错误,更新数据库
if (EntityList.Count > 0)
{
try
{
DC.SaveChanges();
if (ListAdd.Count > 0)
{
BulkInsert
(DC, DC.GetTableName
(), ListAdd);
}
}
catch (Exception e)
{
SetExceptionMessage(e, null);
DoReInit();
return false;
}
}
if (string.IsNullOrEmpty(UploadFileId) == false && Wtm.ServiceProvider != null)
{
var fp = Wtm.ServiceProvider.GetRequiredService();
fp.DeleteFile(UploadFileId, DC.ReCreate());
}
return true;
}
///
/// 批量插入数据库操作,支持SqlServer
///
///
/// data context
///
///
protected static void BulkInsert(IDataContext dc, string tableName, IList list)
{
using (var bulkCopy = new SqlBulkCopy(dc.CSName))
{
bulkCopy.BatchSize = list.Count;
bulkCopy.DestinationTableName = tableName;
var table = new DataTable();
var props = typeof(K).GetAllProperties().Distinct(x => x.Name);
//生成Table的列
foreach (var propertyInfo in props)
{
var notmapped = propertyInfo.GetCustomAttribute();
var notobject = propertyInfo.PropertyType.Namespace.Equals("System") || propertyInfo.PropertyType.IsEnumOrNullableEnum();
if (notmapped == null && notobject)
{
string Name = dc.GetFieldName(propertyInfo.Name);
bulkCopy.ColumnMappings.Add(Name, Name);
table.Columns.Add(Name, Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType);
}
}
//给Table赋值
var values = new object[table.Columns.Count];
foreach (var item in list)
{
var Index = 0;
foreach (var propertyInfo in props)
{
var notmapped = propertyInfo.GetCustomAttribute();
var notobject = propertyInfo.PropertyType.Namespace.Equals("System") || propertyInfo.PropertyType.IsEnumOrNullableEnum();
if (notmapped == null && notobject)
{
values[Index] = propertyInfo.GetValue(item);
Index++;
}
}
table.Rows.Add(values);
}
//检测是否有继承字段,如果存在,进行赋值
string Discriminator = dc.GetFieldName("Discriminator");
if (!string.IsNullOrEmpty(Discriminator))
{
bulkCopy.ColumnMappings.Add("Discriminator", "Discriminator");
table.Columns.Add("Discriminator", typeof(string));
for (int i = 0; i < table.Rows.Count; i++)
{
table.Rows[i]["Discriminator"] = typeof(K).Name;
}
}
bulkCopy.WriteToServer(table);
}
}
#endregion
#region 验证是否空行
///
/// 验证Excel中某行是否为空行
///
/// 行数
/// 列数
/// True代表空行,False代表非空行
private bool IsEmptyRow(XSSFRow row, int colCount)
{
bool result = true;
for (int i = 0; i < colCount; i++)
{
string value = row.GetCell(i, MissingCellPolicy.CREATE_NULL_AS_BLANK).ToString();
if (!string.IsNullOrEmpty(value))
{
result = false;
break;
}
}
return result;
}
#endregion
#region 复制Excel属性
///
/// 复制Excel属性
///
/// 单元格属性
/// 复制后的单元格
private ExcelPropety CopyExcelPropety(ExcelPropety excelPropety)
{
ExcelPropety ep = new ExcelPropety
{
BackgroudColor = excelPropety.BackgroudColor,
ColumnName = excelPropety.ColumnName,
DataType = excelPropety.DataType,
ResourceType = excelPropety.ResourceType,
IsNullAble = excelPropety.IsNullAble,
ListItems = excelPropety.ListItems,
MaxValuseOrLength = excelPropety.MaxValuseOrLength,
MinValueOrLength = excelPropety.MinValueOrLength,
Value = excelPropety.Value,
SubTableType = excelPropety.SubTableType,
CharCount = excelPropety.CharCount,
ReadOnly = excelPropety.ReadOnly,
FormatData = excelPropety.FormatData,
FormatSingleData = excelPropety.FormatSingleData,
FieldName = excelPropety.FieldName
};
List li = new List();
foreach (var item in excelPropety.DynamicColumns)
{
li.Add(CopyExcelPropety(item));
}
ep.DynamicColumns = li;
return ep;
}
#endregion
#region 设置异常信息
///
/// 设置错误信息
///
/// 异常
/// 数据Id
protected void SetExceptionMessage(Exception e, long? id)
{
//检查是否为数据库操作错误
if (e is DbUpdateException)
{
var de = e as DbUpdateException;
if (de.Entries != null)
{
if (de.Entries.Count == 0)
{
ErrorListVM.EntityList.Add(new ErrorMessage { Index = 0, Message = e.Message + e.InnerException?.Message });
}
//循环此错误相关的数据
foreach (var ent in de.Entries)
{
//获取错误数据Id
var errorId = (long)((ent.Entity as TopBasePoco).ExcelIndex);
//根据State判断修改或删除操作,输出不同的错误信息
if (ent.State == EntityState.Deleted)
{
ErrorListVM.EntityList.Add(new ErrorMessage { Index = errorId, Message = CoreProgram._localizer?["Sys.DataCannotDelete"] });
}
else if (ent.State == EntityState.Modified)
{
ErrorListVM.EntityList.Add(new ErrorMessage { Index = errorId, Message = CoreProgram._localizer?["Sys.EditFailed"] });
}
else
{
ErrorListVM.EntityList.Add(new ErrorMessage { Index = errorId, Message = de.Message });
}
}
}
}
//对于其他类型的错误,直接添加错误信息
else
{
if (id != null)
{
ErrorListVM.EntityList.Add(new ErrorMessage { Index = id.Value, Message = e.Message });
}
else
{
ErrorListVM.EntityList.Add(new ErrorMessage { Index = 0, Message = e.Message });
}
}
}
#endregion
#region 验证数据重复
///
/// 判断数据是否在库中存在重复数据
///
/// 要验证的数据
/// 验证表达式
/// null代表没有重复
protected P IsDuplicateData(P Entity, DuplicatedInfo checkCondition)
{
//获取设定的重复字段信息
if (checkCondition != null && checkCondition.Groups.Count > 0)
{
//生成基础Query
var baseExp = DC.Set
().AsQueryable();
var modelType = typeof(P);
ParameterExpression para = Expression.Parameter(modelType, "tm");
//循环所有重复字段组
foreach (var group in checkCondition.Groups)
{
List conditions = new List();
//生成一个表达式,类似于 x=>x.Id != id,这是为了当修改数据时验证重复性的时候,排除当前正在修改的数据
//在每个组中循环所有字段
List props = new List();
//在每个组中循环所有字段
foreach (var field in group.Fields)
{
Expression exp = field.GetExpression(Entity, para);
if (exp != null)
{
conditions.Add(exp);
}
//将字段名保存,为后面生成错误信息作准备
props.AddRange(field.GetProperties());
}
if (conditions.Count > 0)
{
//循环添加条件并生成Where语句
Expression whereCallExpression = baseExp.Expression;
for (int i = 0; i < conditions.Count; i++)
{
whereCallExpression = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { modelType },
whereCallExpression,
Expression.Lambda>(conditions[i], new ParameterExpression[] { para }));
}
var result = baseExp.Provider.CreateQuery(whereCallExpression);
foreach (var res in result)
{
if (IsOverWriteExistData == false)
{
//循环拼接所有字段名
string AllName = "";
foreach (var prop in props)
{
string name = PropertyHelper.GetPropertyDisplayName(prop);
AllName += name + ",";
}
if (AllName.EndsWith(","))
{
AllName = AllName.Remove(AllName.Length - 1);
}
//如果只有一个字段重复,则拼接形成 xxx字段重复 这种提示
if (props.Count == 1)
{
ErrorListVM.EntityList.Add(new ErrorMessage { Message = CoreProgram._localizer?["Sys.DuplicateError", AllName], Index = Entity.ExcelIndex });
}
//如果多个字段重复,则拼接形成 xx,yy,zz组合字段重复 这种提示
else if (props.Count > 1)
{
ErrorListVM.EntityList.Add(new ErrorMessage { Message = CoreProgram._localizer?["Sys.DuplicateGroupError", AllName], Index = Entity.ExcelIndex });
}
}
return res as P;
}
}
}
}
return null;
}
#endregion
protected DuplicatedInfo CreateFieldsInfo(params DuplicatedField
[] FieldExps)
{
DuplicatedInfo
d = new DuplicatedInfo
();
d.AddGroup(FieldExps);
return d;
}
///
/// 创建一个简单重复数据信息
///
/// 重复数据的字段
/// 重复数据信息
public static DuplicatedField
SimpleField(Expression> FieldExp)
{
return new DuplicatedField(FieldExp);
}
///
/// 创建一个关联到其他表数组中数据的重复信息
///
/// 关联表类
/// 指向关联表类数组的Lambda
/// 指向最终字段的Lambda
/// 重复数据信息
public static DuplicatedField
SubField(Expression>> MiddleExp, params Expression>[] FieldExps)
{
return new ComplexDuplicatedField(MiddleExp, FieldExps);
}
public ErrorObj GetErrorJson()
{
var mse = new ErrorObj();
mse.Form = new Dictionary();
var err = ErrorListVM?.EntityList?.Where(x => x.Index == 0).FirstOrDefault()?.Message;
if (string.IsNullOrEmpty(err))
{
Models.IWtmFile fa = null;
if(Wtm.ServiceProvider == null) {
return mse;
}
var fp = Wtm.ServiceProvider.GetRequiredService();
fa = fp.GetFile(UploadFileId, true, DC);
xssfworkbook = new XSSFWorkbook(fa.DataStream);
fa.DataStream.Dispose();
var propetys = Template.GetType().GetFields().Where(x => x.FieldType == typeof(ExcelPropety)).ToList();
List excelPropetys = new List();
for (int porpetyIndex = 0; porpetyIndex < propetys.Count(); porpetyIndex++)
{
ExcelPropety ep = (ExcelPropety)propetys[porpetyIndex].GetValue(Template);
excelPropetys.Add(ep);
}
int columnCount = excelPropetys.Count;
//int excelPropetyCount = excelPropetys.Count;
var dynamicColumn = excelPropetys.Where(x => x.DataType == ColumnDataType.Dynamic).FirstOrDefault();
if (dynamicColumn != null)
{
columnCount = columnCount + dynamicColumn.DynamicColumns.Count - 1;
}
ISheet sheet = xssfworkbook.GetSheetAt(0);
var errorStyle = xssfworkbook.CreateCellStyle();
IFont f = xssfworkbook.CreateFont();
f.Color = HSSFColor.Red.Index;
errorStyle.SetFont(f);
errorStyle.IsLocked = true;
foreach (var e in ErrorListVM?.EntityList)
{
if (e.Index > 0)
{
var c = sheet.GetRow((int)(e.Index - 1)).CreateCell(columnCount);
c.CellStyle = errorStyle;
c.SetCellValue(e.Message);
}
}
MemoryStream ms = new MemoryStream();
xssfworkbook.Write(ms);
ms.Position = 0;
var newfile = fp.Upload("Error-" + fa.FileName, ms.Length, ms);
ms.Close();
ms.Dispose();
err = CoreProgram._localizer?["Sys.ImportError"];
mse.Form.Add("Entity.Import", err);
mse.Form.Add("Entity.ErrorFileId", newfile.GetID());
}
else
{
mse.Form.Add("Entity.Import", err);
}
return mse;
}
}
#region 辅助类
public class ErrorMessage : TopBasePoco
{
[Display(Name = "Sys.RowIndex")]
public long Index { get; set; }
[Display(Name = "Sys.CellIndex")]
public long Cell { get; set; }
[Display(Name = "Sys.ErrorMsg")]
public string Message { get; set; }
}
///
/// 错误数据列表
///
public class TemplateErrorListVM : BasePagedListVM
{
public TemplateErrorListVM()
{
EntityList = new List();
NeedPage = false;
}
protected override IEnumerable> InitGridHeader()
{
return new List>{
this.MakeGridHeader(x => x.Index, 60),
this.MakeGridHeader(x => x.Message)
};
}
public override IOrderedQueryable GetSearchQuery()
{
return EntityList.AsQueryable().OrderBy(x => x.Index);
}
}
#endregion
}