CSFrameworkV6旗舰版 | 基础资料窗体改装主从子表(多级明细表)解决方案|C/S开发框架
CSFrameworkV6旗舰版 - 基础资料窗体改装主从子表(多级明细表)解决方案
一、前言
本文将介绍由单表基础资料窗体改装为主从表窗体的解决方案。
单表基础资料窗体继承 frmBaseDataDictionary 基类窗体。
二、参考界面(改装后)
三、改装过程
3.1 数据编辑页增加明细表标签页及相关组件
增加 TabControl / TabPage页签组件、GridControl表格组件。
3.2 绑定【数据编辑】页面所有文本框及明细表的数据源
修改 DoBindingSummaryEditor 方法,绑定文本框数据源以及明细表格的数据源,参考代码:
protected override void DoBindingSummaryEditor(object summary)
{
this.DoBindingEditorPanel(pcDetailEditor, summary);
this.DoBindingEditorPanel(layoutControl1, summary);
//获取所有明细表数据
var productCode = _BLL.DataBinder.ProductCode;
if (this.IsAddMode) productCode = "--";
var list = _BLL.GetDetails(productCode);
//绑定表格的数据源
gcProductMaterials.DataSource = list.ProductMaterialsList;//用料明细
gcProductCraft.DataSource = list.ProductCraftList;//工序/唛头
gcProductPacking.DataSource = list.ProductPackingList;//打包要求
gcProductProcess.DataSource = list.ProductProcessList;//产品工艺
gcSub.DataSource = list.ProductSubInfoList;//套件、配件信息
gcAttachFile.DataSource = list.ProductLogoFilesList;//唛头文件
}
3.3 DAL层实现 GetDetails 方法,获取所有明细表数据
/// <summary>
/// 获取客户产品所有明细表数据
/// </summary>
/// <param name="productCode">产品编码</param>
/// <returns></returns>
public ProductUpdateModel GetDetails(string productCode)
{
//获取所有明细表
var q_ProductMaterials = _Database.GetQueryable<dt_CustomerProductMaterials>().Where(w => w.ProductCode == productCode);
var q_ProductCraft = _Database.GetQueryable<dt_CustomerProductCraft>().Where(w => w.ProductCode == productCode);
var q_ProductPacking = _Database.GetQueryable<dt_CustomerProductPacking>().Where(w => w.ProductCode == productCode);
var q_ProductProcess = _Database.GetQueryable<dt_CustomerProductProcess>().Where(w => w.ProductCode == productCode);
var q_ProductLogoFiles = _Database.GetQueryable<tb_AttachFile>().Where(w => w.DocType == "Carton" && w.DocID == productCode);
//省略代码......
return new ProductUpdateModel
{
ProductMaterialsList = q_ProductMaterials.ToList(),
ProductCraftList = q_ProductCraft.ToList(),
ProductPackingList = q_ProductPacking.ToList(),
ProductProcessList = q_ProductProcess.ToList(),
ProductLogoFilesList = q_ProductLogoFiles.ToList(),
ProductSubInfoList = listProductSubInfo.ToList(),
};
}
3.4 DAL层重写 Delete 方法,删除主表及所有明细表数据
public override bool Delete(string keyValue)
{
try
{
_Database.BeginTransaction();
var master = _Database.GetQueryable<dt_CustomerProduct>().Where(w => w.isid == keyValue).FirstOrDefault();
var exists = false;
exists = _Database.GetQueryable<tb_Inventory_Cartons>().Any(a => a.ProductCode == master.ProductCode);
if (exists) throw new CustomException("成品库存表已使用该产品,不可删除!");
exists = _Database.GetQueryable<tb_IN_Cartons>().Any(a => a.ProductCode == master.ProductCode);
if (exists) throw new CustomException("成品入库单已使用该产品,不可删除!");
exists = _Database.GetQueryable<tb_DO_Cartons>().Any(a => a.ProductCode == master.ProductCode);
if (exists) throw new CustomException("成品送货单已使用该产品,不可删除!");
var detailA = _Database.GetQueryable<dt_CustomerProductMaterials>().Where(w => w.ProductCode == master.ProductCode).ToList();
var detailB = _Database.GetQueryable<dt_CustomerProductCraft>().Where(w => w.ProductCode == master.ProductCode).ToList();
var detailC = _Database.GetQueryable<dt_CustomerProductPacking>().Where(w => w.ProductCode == master.ProductCode).ToList();
var detailD = _Database.GetQueryable<dt_CustomerProductProcess>().Where(w => w.ProductCode == master.ProductCode).ToList();
var detailF = _Database.GetQueryable<tb_AttachFile>().Where(w => w.DocType == "Carton" && w.DocID == master.ProductCode).ToList();
int count = 0;
count += _Database.Remove<dt_CustomerProduct>(master); //删除主表
count += _Database.Remove<dt_CustomerProductMaterials>(detailA);
count += _Database.Remove<dt_CustomerProductCraft>(detailB);
count += _Database.Remove<dt_CustomerProductPacking>(detailC);
count += _Database.Remove<dt_CustomerProductProcess>(detailD);
count += _Database.Remove<tb_AttachFile>(detailF);
_Database.CommitTransaction();
//保存被删除的数据
if (count > 0)
_Log.Log(DataLogType.delete, "Product删除成功:", nameof(dt_CustomerProduct), master.ProductCode, _Loginer.Account, master);
return count > 0;
}
catch (Exception e)
{
_Database.RollbackTransaction();
throw;
}
}
3.5 界面层重写 DoSave 方法,重写【保存】按钮事件
public override void DoSave(IButtonInfo sender)
{
try
{
frmWaitingEx.ShowMe(this);
this.UpdateLastControl(); //更新最后一个输入控件的数据源
if (!ValidatingData()) return; //检查资料完整性
//明细表数据
var listProductMaterials = gcProductMaterials.GetDataSource<dt_CustomerProductMaterials>();
var listProductCraft = gcProductCraft.GetDataSource<dt_CustomerProductCraft>();
var listProductPacking = gcProductPacking.GetDataSource<dt_CustomerProductPacking>();
var listProductProcess = gcProductProcess.GetDataSource<dt_CustomerProductProcess>();
var listProductLogoFiles = gcAttachFile.GetDataSource<tb_AttachFile>();
//调用BLL层接口保存数据
bool result = _BLL.Update(_UpdateType,
listProductMaterials,
listProductCraft,
listProductPacking,
listProductProcess,
listProductLogoFiles);
if (result)
{
var dt = _BLL.GetDataByKey(_BLL.DataBinder.isid);//获取最新数据
this.UpdateSummaryRow(dt); //刷新表格当前记录
this.DoBindingSummaryEditor(dt);
this.DoSave_ResetState();//保存成功后要设置各种状态,调用基类通用逻辑
this.NotifyDataDictChanged<dt_CustomerProduct>();
}
else
{
Msg.Warning("保存失败!");
}
}
finally
{
frmWaitingEx.HideMe(this);
}
}
3.6 BLL 层重载Update 方法,用于保存数据
public virtual bool Update(UpdateType type,
List<dt_CustomerProductMaterials> listProductMaterials,
List<dt_CustomerProductCraft> listProductCraft,
List<dt_CustomerProductPacking> listProductPacking,
List<dt_CustomerProductProcess> listProductProcess,
List<tb_AttachFile> listProductLogoFiles)
{
//更新公共字段的数据
SetDetailCommonValue(_DataBinder);
var data = CreateSaveData(type, _DataBinder);
var input = new ProductUpdateModel
{
MasterDataUpdate = data,
ProductCraftList = listProductCraft,
ProductMaterialsList = listProductMaterials,
ProductPackingList = listProductPacking,
ProductProcessList = listProductProcess,
ProductLogoFilesList = listProductLogoFiles,
};
return _Bridge.Update(input);
}
3.7 DAL层重载 Update 方法,用于保存数据
public bool Update(ProductUpdateModel input)
{
try
{
_Database.BeginTransaction();
//新增客户产品,自动生成产品序号
if (input.MasterDataUpdate.listAdded.Count > 0)
{
var sn= DocNoHelper.GetDataSN(_Database, "CP", true, 8, "", _Loginer.Account);//生成客户产品编码
input.MasterDataUpdate.listAdded.First().ProductCode = sn;
}
//提交主表
base.Update(input.MasterDataUpdate, _Database, false);
//获取产品编码,作为所有明细表的外键值
var ProductCode = input.MasterDataUpdate.VisibleList.First().ProductCode;
#region 提交明细表:产品物料
SetCommonValue<dt_CustomerProductMaterials>(input.ProductMaterialsList);
if (input.ProductMaterialsList != null)
{
foreach (var v in input.ProductMaterialsList)
{
//新增记录,设置默认值
if (v.isid.IsEmpty()) v.isid = IdHelper.GetId();
if (v.ProductCode.IsEmpty()) v.ProductCode = ProductCode;
}
//删除旧数据
_Database.Remove<dt_CustomerProductMaterials>(w => w.ProductCode == ProductCode);
//保存数据
_Database.Add(input.ProductMaterialsList);
}
#endregion
#region 提交明细表:产品工艺
SetCommonValue<dt_CustomerProductCraft>(input.ProductCraftList);
if (input.ProductCraftList != null)
{
foreach (var v in input.ProductCraftList)
{
//新增记录,设置默认值
if (v.isid.IsEmpty()) v.isid = IdHelper.GetId();
if (v.ProductCode.IsEmpty()) v.ProductCode = ProductCode;
}
//删除旧数据
_Database.Remove<dt_CustomerProductCraft>(w => w.ProductCode == ProductCode);
//保存数据
_Database.Add(input.ProductCraftList);
}
#endregion
#region 提交明细表:打包要求
SetCommonValue<dt_CustomerProductPacking>(input.ProductPackingList);
if (input.ProductPackingList != null)
{
foreach (var v in input.ProductPackingList)
{
//新增记录,设置默认值
if (v.isid.IsEmpty()) v.isid = IdHelper.GetId();
if (v.ProductCode.IsEmpty()) v.ProductCode = ProductCode;
}
//删除旧数据
_Database.Remove<dt_CustomerProductPacking>(w => w.ProductCode == ProductCode);
//保存数据
_Database.Add(input.ProductPackingList);
}
#endregion
#region 提交明细表:产品工序
SetCommonValue<dt_CustomerProductProcess>(input.ProductProcessList);
if (input.ProductProcessList != null)
{
foreach (var v in input.ProductProcessList)
{
//新增记录,设置默认值
if (v.isid.IsEmpty()) v.isid = IdHelper.GetId();
if (v.ProductCode.IsEmpty()) v.ProductCode = ProductCode;
}
//删除旧数据
_Database.Remove<dt_CustomerProductProcess>(w => w.ProductCode == ProductCode);
//保存数据
_Database.Add(input.ProductProcessList);
}
#endregion
#region 提交明细表:唛头文件
if (input.ProductLogoFilesList != null)
{
foreach (var v in input.ProductLogoFilesList)
{
//新增记录,设置默认值
if (v.FileID.IsEmpty())
{
v.FileID = IdHelper.GetId();
v.DocID = ProductCode;
v.DocType = "Carton";
}
}
//删除旧数据
_Database.Remove<tb_AttachFile>(w => w.DocType == "Carton" && w.DocID == ProductCode);
//保存数据
_Database.Add(input.ProductLogoFilesList);
}
#endregion
_Database.CommitTransaction();
return true;
}
catch (System.Exception)
{
_Database.RollbackTransaction();
throw;
}
}
3.8 提交的数据模型 ProductUpdateModel
/// <summary>
/// 客户产品资料-保存数据模型
/// </summary>
public class ProductUpdateModel
{
//主表数据
public MasterDataUpdate<dt_CustomerProduct> MasterDataUpdate { get; set; }
//明细表数据
public List<dt_CustomerProductMaterials> ProductMaterialsList { get; set; }
public List<dt_CustomerProductCraft> ProductCraftList { get; set; }
public List<dt_CustomerProductPacking> ProductPackingList { get; set; }
public List<dt_CustomerProductProcess> ProductProcessList { get; set; }
public List<tb_AttachFile> ProductLogoFilesList { get; set; }
public List<res_SOs> ProductSubInfoList { get; set; }
}
四、获取实例源码
CSFrameworkV6用户请联系作者,获得本教程完整源码。
扫一扫加作者微信