查询开发框架

栏目:u9cloud知识作者:用友来源:用友发布:2024-08-20浏览:2

查询开发框架

概述

BE查询方式的执行过程

  1. 根据BE实体的元数据来生成默认的CaseModel
  2. 用户在查询方案画面中,调整条件、栏目、排序
  3. 使用BEQueryStrategyImpl将CaseModel转化成UIView
  4. 调用平台的UIView机制生成并执行OQL,将返回的结果放入UIView中,然后绑定到UIGrid 上

DTO查询方式的执行过程

  1. 根据所设计的DTO的元数据来生成默认的CaseModel 
  2. 用户在查询方案画面中,调整条件、栏目、排序
  3. 使用DTOQueryStrategyImpl获得CaseModel转化成QryCommonParaObj,并传入到查询BP中执行
  4. 查询BP根据QryCommonParaObj来实现具体的查询逻辑,并将结果返回并填充UIView中,然后绑定到UIGrid 上

BE方式与DTO方式的比较

 

BE方式

DTO方式

复杂度

逻辑简单逻辑复杂(多次查询、临时表)

CaseModel的生成方式

根据BE元数据来生成CaseModel根据DTO元数据来生成CaseModel

OQL

平台负责生成OQL自己拼写OQL

实体间的关系

一个主实体,多个子实体,能使用A.B.C的oql语法多个实体,之间为弱引用关系,不能通过A.B.C的oql语句来查询,需要自己拼接oql语句。或通过临时表来做二次查询。或使用DataTable处理

 

BE方式查询的设计与开发

1.设计期—UI端

与列表UI开发的不同点:选择“查询模板”(没有删除和新增按钮),根据WebPart关联方式来选择如何拖UIView中的字段(参见WebPart关联部分)

 

命名规范:与列表开发类似,但要将其中的BList变成BQry,一定要注意这点

UI端代码—Ation部分

//数据加载的扩展

private void  this.CurrentPart.GetUFControlByName(this.CurrentPart.TopLevelContainer, "DataGrid1") as IUFDataGrid;

    BEQueryStrategyImpl beQryStrategyImpl = new BEQueryStrategyImpl(this.CurrentState, EntityFullName, QryModelID, this.CurrentModel.QCDocLine, UIGrid,1);

beQryStrategyImpl.Adjust();

 

this.MainView.CurrentFilter.OPath = QryService.GetDefaultOpath((UFSoft.UBF.UI.FormProcess.BaseWebForm)(this.CurrentPart));

 

//如果本Webpart是消费者,则需要处理传入的Webpart关联参数,可以参见下面的方式(这部分要根据自己的情况编写):

    if (this.MainView.CurrentFilter.Parameters != null && this.MainView.CurrentFilter.Parameters.Count > 0)

    {

        string sOPath = this.MainView.CurrentFilter.OriginalOPath;

        foreach (IUIParameter paradata in this.MainView.CurrentFilter.Parameters)

        {

            if(paradata.DataValue!=null)

                sOPath = sOPath.Replace(paradata.Name, paradata.DataValue.ToString());

        }

        this.MainView.CurrentFilter.OPath += " and " + sOPath;//将“查询方案中的条件”与“Webpart关联的传入参数”合到一起

}

 

//处理排序

this.CurrentModel.QCDocLine.CurrentFilter.OrderBy = QryService.GetOrderByOpath((BaseWebForm)(this.CurrentPart));

 

//增加代码,调整UIView

 

    this.CurrentModel.QCDocLine.Clear();

    this.NavigateAction.FirstPage(null);

    if (this.MainView.Records.Count == 0)

    {

        this.CurrentPart.ShowWindowStatus(PDResource.GetNoRecordSucessInfo());

    }

    else

    {

        this.CurrentPart.ShowWindowStatus(PDResource.GetFindSucessInfo());

    }

}

 

public void InitCaseModel()

{

    IUFDataGrid UIGrid = this.CurrentPart.GetUFControlByName(this.CurrentPart.TopLevelContainer, "DataGrid1") as IUFDataGrid;

BEQueryStrategyImpl beQryStrategyImpl = new BEQueryStrategyImpl(this.CurrentState, EntityFullName, QryModelID, this.CurrentModel.QCDocLine, UIGrid,1);

//增加代码,调整BE元数据加载方式

CaseModel caseModel = beQryStrategyImpl.GetQryModel();

//增加代码,调整CaseModel

    QryService.SetCaseModelToSession((BaseWebForm)(this.CurrentPart), caseModel);

}

UI端代码—WebPart部分

public void After UpdatePanelUpdateMode.Always; 

 

//this.IsProviding = true;//如果在Webpart关联中,本WebPart是提供者,则需要加入这段话

 

    //绑定BE方式的分页事件

GridNavigateAction.GetInstance().AttachMakePageEvent(this.Action, this.DataGrid1);

}

 

public void BeforeUIModelBinding()

{

    if (QryService.IsCallInitCaseModel(this.DataGrid1))

    {

        this.Action.InitCaseModel();

    }

    if (QryService.IsCallAdjust(this.DataGrid1))

    {

        this.Action.QueryAdjust();

    }

    else

    {

        QryService.SetGridWidthToCase(this.CurrentState, FormID, this.DataGrid1);

    }

}

 

public void AfterUIModelBinding()

{

QryService.BindEnum("DDLCase", this, this.Action.QryModelID);

//加入调整UIGrid的代码

}

UI端代码—BE正拖模型方式下的Action部分

以往做列表时,都是倒拖,即在UIView中拖子,从子找到主。

还有一种是正拖方式,即从主找到子,即生成CaseModel时,要加载集合特性的子。这需要在InitCaseModel添加代码,如下颜色标记:

public void InitCaseModel()

{

    QryService.ClearSession((BaseWebForm)(this.CurrentPart));

    IUFDataGrid UIGrid = this.CurrentPart.GetUFControlByName(this.CurrentPart.TopLevelContainer, "DataGrid1") as IUFDataGrid;

 

    BEQueryStrategyImpl beQryStrategyImpl = new BEQueryStrategyImpl(this.CurrentState, EntityFullName, QryModelID, this.MainView, UIGrid, 2);

beQryStrategyImpl.IsLoadCollectionAttrs = true;

 

采用正拖模型,转成oql语句执行后,得到的结果是一个主对应多个子的形式,如下:

ID(主ID)主表中的字段子ID子表中的字段。。。
13001 
13002 
24001 
25001 

如果是这种样式的记录,在添充到UIView.Recors中时,平台对于重复ID的记录,只取第一条记录。如下:

ID(主ID)主表中的字段子ID子表中的字段。。。
13001 
24001 

 

因此,如果想要展现第一种样式的数据,必须对ID字段做一些处理,即生成一个顺序号来代替主ID字段。这需要在QueryAdjust中改变UIView中UIField,代码如下:

public void QueryAdjust()

{

    IUFDataGrid UIGrid = this.CurrentPart.GetUFControlByName(this.CurrentPart.TopLevelContainer, "DataGrid1") as IUFDataGrid;

   BEQueryStrategyImpl beQryStrategyImpl = new BEQueryStrategyImpl(this.CurrentState, EntityFullName, QryModelID, this.CurrentModel.PayrollSupply, UIGrid, 2);

beQryStrategyImpl.Adjust();

 

   this.CurrentModel.PayrollSupply.CurrentFilter.OPath = QryService.GetDefaultOpath((BaseWebForm)(this.CurrentPart));

   this.CurrentModel.PayrollSupply.CurrentFilter.OrderBy = QryService.GetOrderByOpath((BaseWebForm)(this.CurrentPart));

 

    //将原来的“ID”变成“顺序号row_number”,注意大小写(oql中的关键字应该全是小写的)

    IUIField uiField = this.MainView.Fields["ID"];

    uiField.AttributeName = "row_number() over(order by ID asc)";

 

    if (this.MainView.Fields["PID"] == null)

    {

        //新增一个PID来存放“主表ID”-----------------------↓ID的别名------------↓字段类型-----------------------↓原字段名

        IUIField fieldParentID = new UIField(this.MainView, "PID", Type.GetType("System.Int64"), true, "0", "PID", "ID", false, true, false, "", false);

        this.MainView.Fields.Add(fieldParentID);

    }

this.MainView.BuildFieldIndexes();//调整UIView中UIField结构后,必须重建其字段索引

 

   this.CurrentModel.Views["PayrollSupply"].Clear();

   this.NavigateAction.FirstPage(null);

 

    if (this.MainView.Records.Count == 0)

    {

       this.CurrentPart.ShowWindowStatus(PDResource.GetNoRecordSucessInfo());

    }

    else

    {

       this.CurrentPart.ShowWindowStatus(PDResource.GetFindSucessInfo());

    }

}

该段代码的CC路径:/View/U9UICode/U9.VOB.PD.HR/Pay/Code/PayrollSupplyUI/

DTO方式查询的设计与开发

DTO方式查询分为五个环节:设计期(UI端、DTO、BP端),代码(UI、BP)

 

设计期—UI端

与列表UI开发的不同点:选择“查询模板”(没有删除和新增按钮),根据WebPart关联方式来选择如何拖UIView中的字段(参见WebPart关联文档)

 

命名规范:与列表开发类似,但要将其中的BList变成BQry,一定要注意这点

设计期—DTO设计

在本方案中用DTO来定义查询的待选项集合,并且该DTO必须作为查询BP的返回值(IList)。

数据类型限制

一般来说,DTO中的每一个属性就对应一个待选项,作为约定,其数据类型必须是原生类型、强类型的实体Key类型、枚举类型。下图的System下的前面若干项是可选的。xml、对象类型、空类型、实体key类型是不可选的。

 

所谓的强类型实体key的定义应如下图:

 

先选上一个实体,然后在实体key选项框中打上勾。

 

作为约定,强类型的实体Key属性不作为待选项,但可以作为条件及排序待选项,并且不能展开下级。

查询DTO设计中的注意事项:

  1. 必须有ID字段
  2. 如果返回的记录中ID列有重复, Grid会中会只显示一行记录。对于这种情况,可以将row_number()做为ID列。(可参考《查询列表常见问题及解决办法》中的“正拖模型”部分)
  3. 属性的名称用于拼OQL时Seclect子句的别名,同时也会对应UIView的UIField名称及Grid的列名。(理解这点很重要!!!!)
  4. 选择合理的字段类型
  5. 根据业务需求,设计合理的查询属性(条件待选、栏目待选、排序待选、默认栏目)
  6. 每次调整DTO后,要注意重新构造并执行相应的sql脚本(发布元数据)

设计期—BP设计

入口参数

所有查询BP的入口参数的类型都必须是查询公共部份提供的DTO(查询BP通用入参DTO)。

 

此DTO中包含有已选栏目、过滤、排序等信息,BP开发人员可根据这些参数,构造符合业务的OQL语句。定义方式如下图:

 

返回值

所有查询BP都必须以描述待选项集合的DTO集合为BP的返回值

应用版型

为了让查询BP在构造时产生骨架代码,在BP设计器中要选中该BP,点右键,点菜单[应用版型],在树中选上“查询BP版型”,如下图:

 

步骤一:

步骤二:

在版型树上选中[查询BP版型]。

BP端代码示例

在设计BP时,给BP加上版型[查询BP版型],在构造时便会生成查询BP的骨架代码,查询BP的开发人员,只需要在适当的位置按业务逻辑写上相应的代码即可。骨架代码分为两个Partial类。其中第一部份只有一个Do方法,在Do方法中BP实现者要调用第二部份的私有方法DoProcess方法,并将BP的参数作为方法的参数。如下:

    internal partial class SOShiplineSumBQueryBPImpementStrategy : BaseStrategy

    {

        public SOShiplineSumBQueryBPImpementStrategy() { }

 

        public override object Do(object obj)

        {

            SOShiplineSumBQueryBP bpObj = (SOShiplineSumBQueryBP)obj;

            return DoProcess(bpObj.QryInParameter);//BP实现者要加上这句话

        }

    }

 

private object DoProcess(UFIDA.U9.Query.QueryCaseBP.QryCommonParaObj bpParameter)

{

    UFIDA.UBF.Query.CommonService.QryPaginateService ps = 

        new UFIDA.UBF.Query.CommonService.QryPaginateService(bpParameter, isNeedTempTable());

    if (ps.isProcessBusiness)

    {

        string oql = DoLogic(bpParameter);

        return ps.FindDataByPage(GetEntityFullName(), oqlBuildByTempTable(), oql);

    }

    else

    {

        return ps.FindDataByPage();

    }

}

 

internal partial class SOLineSumBQueryBPImpementStrategy

{

   //主实体FullName

    private string GetEntityFullName()

    {

         return "UFIDA.U9.SM.SO.SOLine";

    }

    /// 

 

    /// 分页内部是否需要使用临时表机制,对于数据量比较小的查询,没有必要采用临时表

    /// 缓存第一次查询的结果,每次重查就行了,否则第一次查询时页面加载会慢些。由BP

    /// 开发人员自己判断。

    /// 

 

    /// 

    private bool isNeedTempTable()

    {

        return true;

    }//end isTempTable 

 

    /// 

 

    /// 是否基于临时表构造的OQL,对于基于临时表的查询,分页服务内部不需要多语的处理;

    /// 基于业务表的查询,则需要。此处由BP开发人员根据实际情况返回正确的值。

    /// 

 

    /// 

    private bool oqlBuildByTempTable()

    {

        return false;

    }//end isNeedMultiLang

 

    /// 

 

    /// 执行业务逻辑,返回OQL串,由BP开发人员添加代码。

    /// 参数bpParameter中带有已选栏目、过滤及排序信息

    /// 

 

    /// 

    private string DoLogic(UFIDA.U9.Query.QueryCaseBP.QryCommonParaObj bpParameter)

{

     //根据业务逻辑,返回OQL串

    }

 

 

代码的第二部份中DoProcess方法,由前面的partial类中的Do方法调用。不需要BP开发人员作任何处理。 需要BP开发人员作处理的是以下几个方法:

方法名称

用途

GetEntityFullName主实体FullName,对于基于临时表的OQL则为临时表表名。
isNeedTempTable分页内部是否需要使用临时表机制,对于数据量比较小的查询,没有必要采用临时表缓存第一次查询的结果,每次重查就行了,否则第一次查询时页面加载会慢些。由BP开发人员自己判断。
oqlBuildByTempTable是否基于临时表构造的OQL,对于基于临时表的查询,分页服务内部不需要多语的处理;基于业务表的查询,则需要。此处由BP开发人员根据实际情况返回正确的值。
DoLogic

执行业务逻辑,返回OQL串,由BP开发人员添加代码。

参数bpParameter中带有已选栏目、过滤及排序信息。

 

辅助工具

如果所设计的查询DTO中的属性来源于多个实体,字段多,实体间关系复杂,则可以使用SimpleOqlTool来拼接OQL语句。SimpleOqlTool的使用方法与报表DataCommand中的DS设计相同。这里可以借用报表开发工具中的DataCommand代码生成工具,便捷的处理DTO属性名称和实体字段的对应关系。比如,由辅助工具生成的代码片断如下:

 

    ///

 

    /// 销售订单计划行.交期  DateTime                

    ///

 

    public readonly static string SOShipline_RequireDate = "SOShipline_RequireDate";

    ///

 

    /// 销售订单计划行.数量2  Decimal                

    ///

 

public readonly staticstring SOShipline_ShipPlanQtyTBU = "SOShipline_ShipPlanQtyTBU";

 

    // 销售订单计划行.交期   DateTime

    map.Add(SOShipline_RequireDate, "SOShipline.RequireDate");

    // 销售订单计划行.数量2   Decimal

    map.Add(SOShipline_ShipPlanQtyTBU, "SOShipline.ShipPlanQtyTBU");

 

其中,SOShipline_RequireDate和SOShipline_ShipPlanQtyTBU就是我们在DTO定义的属性名称

SOShipline.RequireDate与SOShipline.ShipPlanQtyTBU就是实体的字段

 

那么,最后通过工具拼接成OQL语句会是这样的:

Select SOShipline.RequireDate as SOShipline_RequireDate, SOShipline.ShipPlanQtyTBU as SOShipline_ShipPlanQtyTBU,… from UFIDA::U9::SM::SO::SOShipline as SOShipline

 

这样就建立起了DTO属性名称与实体字段的对应关系,并且通过这个辅助工具生成代码,能极小减轻我们的工作量。再次强调,DTO设计期的字段名称要与辅助工具中定义的别名一致。

在UBF中打开一个报表,然后选择“报表—DataCommand工具集—DataCommand代码生成”

弹出“解决方案对话框”

 

1. 服务组名称:由于我们只是借用这个报表工具生成代码,所以服务组名可以随意选一个。

2 生成路径:生成的报表项目的存放路径。

3 DataCommand模型:对于查询开发,不需要选择该项

点击“下一步”弹出 选择字段信息对话框

点击“选择字段”按钮 ,弹出 选择实体信息对话框。

在实体名称中输入要查询的实体,点击“查询按钮”,列表中出现你选择的实体信息。

在DataGrid中双击你要使用的实体,在下面的属性DataGrid中,就会列出该实体的全部属性。

在实体名称中,输入所需的,如Person,则会将与实体名称中包含Person的都列出来。

然后双击一个指定的实体,则会显示出该实体的全部字段。

这里面关键的一点是:要仔细写出各个字段的别名,这个别名要与DTO设计中的字段名一致。(这点一定要注意)

如下图:

 

注意: 粗体部分表示可以双击,进入该实体或者属性类型来选择它下面的字段属性。

选择实体字段的规则:

基本属性:作为当前实体的一个字段。

实体属性:自动选择实体的ID,Code,Name(没有就不取)

属性类型:自动取属性类型下的所有属性,如果该属性又是实体则取该实体的Code,Name属性

模式匹配:

在模式匹配文本框中输入模式字符串,点击匹配,在属性DataGrid中就会列出匹配的字段信息

点击显示全部属性,就会显示出该实体的全部属性。

 

选中DataGrid的多行后,在 DataGrid的“选中”列头上右击鼠标,回弹出 选中,取消菜单,进行多选操作。

 

返回按钮:从子实体中导航到主实体。如:Address.Contact.Enterprise,点击返回时:直接显示 Address的属性

返回上级:从子实体导航到上一级实体。如:Address.Contact.Enterprise,点击返回时:直接显示 Contact的属性

 

在所有的字段都选择完成后,点击确定按钮

你刚才选择的所有属性就出现在选择字段对话框中的DataGrid中了。如下图:

这个画面中的CheckBox框,对查询开发没有用过,点击下一下跳过即可。

 

操作提示:

1 在DataGrid的行上双击会弹出选择实体属性对话框,并在实体属性DataGrid中列出实体全称的末级实体的所有属性。(双击当前行进入末级实体选择界面)

 

2 先选择DataGrid 的多行,在 每一个带CheckBox的列上点击右键可以对选择的多行进行多选操作

3 删除多行:

选择DataGrid的多行,直接按键盘上的Delete键,弹出是否删除的确认框,选择是就会删除所选的行。

 

点击下一步 弹出 DataCommand信息对话框。

在该对话框中输入DataSource 名称 ,对于查询开发来说,我们只需要生成DataSource即可,点击下一步。

点击下一步 弹出信息确认对话框。

 

在该对话框中如果你选择了只生成 DataSoruce复选框 ,则将只生成DataSource .

在信息确认界面,如果你确认前面的选择无误后,

点击完成。稍等片刻 ,代码生成完成。

如果你选择了代码生成完成后自动打开 本项目复选框 ,将自动打开该项目。

 

将生成的字段映射部分代码copy到查询BP中。需要copy的代码有:

 

#region 实体字段别名定义

#region 实体属性对应的别名定义

。。。

。。。

。。。

     #endregion

#endregion

 

#region 静态构造函数

     static XXXX()

{

     #region 初始化列栏目名称    

                。。。

。。。

。。。

        #endregion

     }

#endregion

具体的使用细节,参见示例:

#region implement strategy    

    ///

 

    /// Impement Implement

    ///

    ///

 

    internal partial class QueryBPImpementStrategy : BaseStrategy

    {

        public QueryBPImpementStrategy() { }


 

        public override object Do(object obj)

        {                       

            QueryBP bpObj = (QueryBP)obj;

return DoProcess(bpObj.QryInParameter);

            //get business operation context is as follows

            //IContext context = ContextManager.Context 

            

            //auto generating code end,underside is user custom code

            //and if you Implement replace this Exception Code...

//throw new NotImplementedException();

        }       

    }

 

#region QueryBP Stereotype

internal partial class QueryBPImpementStrategy

{

//实体FullName

private string GetEntityFullName()

{

//TODO:

//return string.Empty;

return "UFIDA.U9.SM.SO.SOShipline";

}

///

 

/// 分页内部是否需要使用临时表机制,对于数据量比较小的查询,没有必要采用临时表

/// 缓存第一次查询的结果,每次重查就行了,否则第一次查询时页面加载会慢些。由BP

/// 开发人员自己判断。

///

 

///

private bool isNeedTempTable()

{

return true;

}//end isTempTable


 

///

 

/// 是否基于临时表构造的OQL,对于基于临时表的查询,分页服务内部不需要多语的处理;

/// 基于业务表的查询,则需要。此处由BP开发人员根据实际情况返回正确的值。

///

 

///

private bool oqlBuildByTempTable()

{

return false;

}//end isNeedMultiLang


 

///

 

/// 执行业务逻辑,返回OQL串,由BP开发人员添加代码。

/// 参数bpParameter中带有已选栏目、过滤及排序信息

///

 

///

private string DoLogic(UFIDA.U9.Query.QueryCaseBP.QryCommonParaObj bpParameter)

{

DoMap();

//必须引用UFIDA.UBF.Report.App.Data.dll

UFIDA.UBF.Report.App.Data.SimpleOqlTool simpleTool = new UFIDA.UBF.Report.App.Data.SimpleOqlTool();


 

//处理栏目,形成Select子句

foreach (QryColumnItem columnitem in bpParameter.QryColumnItems)

{

string columAlias = GetParseName(this.map[columnitem.ColumnAlias]);

simpleTool.AddSelect(columAlias, columnitem.ColumnAlias);

}

//将排序项加入栏目

foreach (QrySortItem sortItem in bpParameter.QrySortItems)

{

simpleTool.AddSelect(GetParseName(this.map[sortItem.ColumnName]), sortItem.ColumnName);

}

//ID

string alias = GetParseName(ID);

simpleTool.AddSelect(alias, ID);

//SOLine_ID

alias = GetParseName(this.map[SOLine_ID]);

simpleTool.AddSelect(alias, SOLine_ID);

//Org_ID

alias = GetParseName(this.map[Org_ID]);

simpleTool.AddSelect(alias, Org_ID);

//SOLine_SO_ID

alias = GetParseName(this.map[SOLine_SO_ID]);

simpleTool.AddSelect(alias, SOLine_SO_ID);

#region //精度

//销售单位_精度_精度

alias = GetParseName(this.map[TU_Round_Precision]);

simpleTool.AddSelect(alias, TU_Round_Precision);

//销售单位_精度_舍入类型

alias = GetParseName(this.map[TU_Round_RoundType]);

simpleTool.AddSelect(alias, TU_Round_RoundType);

//销售单位_精度_舍入值

alias = GetParseName(this.map[TU_Round_RoundValue]);

simpleTool.AddSelect(alias, TU_Round_RoundValue);

//销售基准单位_精度_精度

alias = GetParseName(this.map[TBU_Round_Precision]);

simpleTool.AddSelect(alias, TBU_Round_Precision);

//销售基准单位_精度_舍入类型

alias = GetParseName(this.map[TBU_Round_RoundType]);

simpleTool.AddSelect(alias, TBU_Round_RoundType);

//销售基准单位_精度_舍入值

alias = GetParseName(this.map[TBU_Round_RoundValue]);

simpleTool.AddSelect(alias, TBU_Round_RoundValue);

#endregion

//处理条件,形成Where子句

if (bpParameter.FilterOpath != "")

simpleTool.AddCondition(bpParameter.FilterOpath);

else

simpleTool.AddCondition("1=0");

//3.处理Order

//foreach (QrySortItem sortItem in bpParameter.QrySortItems)

//{

// if (this.map[sortItem.ColumnName] != null && this.map[sortItem.ColumnName] != "")

// {

// string sortName = GetParseName(map[sortItem.ColumnName]);

// if (sortItem.OrderType == UFIDA.U9.Query.QueryCaseBE.OrderType.Ascend)

// simpleTool.AddOrder(sortName, true);

// else

// simpleTool.AddOrder(sortName, false);

// }

//}

//处理From部份,形成From子句

simpleTool.SetFromClause(" UFIDA::U9::SM::SO::SO SO left join UFIDA::U9::SM::SO::SOLine SOLine on SO.ID = SOLine.SO "

+ " left join UFIDA::U9::SM::SO::SOShipline SOShipLine on SOLine.ID=SOShipLine.SOLine ");


 

//获取OQL串

string selectResult = simpleTool.GetOqlString();


 

//订单版本处理

StringBuilder sbRel = new StringBuilder(2048);

string selectResultHis = selectResult.Replace("UFIDA::U9::SM::SO::SOShipline SOShipLine", "UFIDA::U9::SM::SO::SOShiplineHis SOShipLine");

selectResultHis = selectResultHis.Replace("UFIDA::U9::SM::SO::SOLine SOLine", "UFIDA::U9::SM::SO::SOLineHis SOLine");

selectResultHis = selectResultHis.Replace("UFIDA::U9::SM::SO::SO SO", "UFIDA::U9::SM::SO::SOHis SO");

sbRel.Append("select * from ( ");

sbRel.Append(selectResult);

sbRel.Append(" union all ");

sbRel.Append(selectResultHis);

sbRel.Append(" ) as A ");

//处理排序

if (bpParameter.QrySortItems.Count > 0)

sbRel.Append(" order by ");

foreach (QrySortItem sortItem in bpParameter.QrySortItems)

{

if (sortItem.OrderType == UFIDA.U9.Query.QueryCaseBE.OrderType.Ascend)

{

sbRel.Append(sortItem.ColumnName);

sbRel.Append(" asc ");

}

else

{

sbRel.Append(sortItem.ColumnName);

sbRel.Append(" desc ");

}

sbRel.Append(",");

}

selectResult = sbRel.ToString();

if (selectResult.EndsWith(","))

selectResult = selectResult.Substring(0, selectResult.Length - 1);


 

return selectResult;

} //end DoLogic

///

 

/// 获取解析后的字段名称

///

 

///

///

private string GetParseName(string ItemName)

{

string name = ItemName;

if (name.StartsWith("SOLine.SO"))

name = name.Replace("SOLine.SO", "SO");

//else if (name.StartsWith("SO"))

// name = name;

else

name = "SOShipLine." + name;

return name;

}


 

///

 

/// 这部份代码查询开发人员不要作修改

/// 删除Do方法中的

/// throw new NotImplementedException();

/// 在Do方法中直接加上一句:

/// return DoProcess(bpObj.QryInParameter);

///

 

///

///

private object DoProcess(UFIDA.U9.Query.QueryCaseBP.QryCommonParaObj bpParameter)

{

UFIDA.UBF.Query.CommonService.QryPaginateService ps = new UFIDA.UBF.Query.CommonService.QryPaginateService(bpParameter, isNeedTempTable());

if (ps.isProcessBusiness)

{

string oql = DoLogic(bpParameter);

return ps.FindDataByPage(GetEntityFullName(), oqlBuildByTempTable(), oql);

}

else

{

return ps.FindDataByPage();

}

}

}

 

internal partial class QueryBPImpementStrategy

{

private IDictionary map = new Dictionary();


 

#region 实体属性对应的别名定义

public readonly static string ID = "ID";

public readonly static string Org_Name = "Org_Name";

public readonly static string SOLine_SO_DocNo = "SOLine_SO_DocNo";

public readonly static string SOLine_SO_BusinessDate = "SOLine_SO_BusinessDate";

public readonly static string SOLine_SO_OrderBy_Name = "SOLine_SO_OrderBy_Name";

public readonly static string SOLine_DocLineNo = "SOLine_DocLineNo";

public readonly static string SOLine_ItemInfo_ItemName = "SOLine_ItemInfo_ItemName";

public readonly static string SOLine_ItemInfo_ItemCode = "SOLine_ItemInfo_ItemCode";

public readonly static string DocSubLineNo = "DocSubLineNo";

public readonly static string ShipToSite_Name = "ShipToSite_Name";

public readonly static string ItemInfo_ItemName = "ItemInfo_ItemName";

public readonly static string ItemInfo_ItemCode = "ItemInfo_ItemCode";

public readonly static string SupplySource = "SupplySource";

public readonly static string SupplyOrg_Name = "SupplyOrg_Name";

public readonly static string WH_Name = "WH_Name";

public readonly static string DeliveryDate = "DeliveryDate";

public readonly static string ShipPlanQtyTU = "ShipPlanQtyTU";

public readonly static string ShipPlanQtyTBU = "ShipPlanQtyTBU";

public readonly static string SOLine_ID = "SOLine_ID";

public readonly static string Org_ID = "Org_ID";

public readonly static string TU_Round_Precision = "TU_Round_Precision";

public readonly static string TU_Round_RoundType = "TU_Round_RoundType";

public readonly static string TU_Round_RoundValue = "TU_Round_RoundValue";

public readonly static string TBU_Round_Precision = "TBU_Round_Precision";

public readonly static string TBU_Round_RoundType = "TBU_Round_RoundType";

public readonly static string TBU_Round_RoundValue = "TBU_Round_RoundValue";

public readonly static string SOLine_SO_ID = "SOLine_SO_ID";

public readonly static string Seiban_SeibanNO = "Seiban_SeibanNO";

#endregion


 

private void DoMap()

{

//ID

map.Add(ID, "ID");

//组织

map.Add(Org_Name, "Org.Name");

//订单号

map.Add(SOLine_SO_DocNo, "SOLine.SO.DocNo");

//订单日期

map.Add(SOLine_SO_BusinessDate, "SOLine.SO.BusinessDate");

//订货客户名称

map.Add(SOLine_SO_OrderBy_Name, "SOLine.SO.OrderBy.Name");

//订单行号

map.Add(SOLine_DocLineNo, "SOLine.DocLineNo");

//订单行.品名

map.Add(SOLine_ItemInfo_ItemName, "SOLine.ItemInfo.ItemName");

//订单行.料号

map.Add(SOLine_ItemInfo_ItemCode, "SOLine.ItemInfo.ItemCode");

//订单子行号

map.Add(DocSubLineNo, "DocSubLineNo");

//收货位置

map.Add(ShipToSite_Name, "ShipToSite.Name");

//订单子行.品名

map.Add(ItemInfo_ItemName, "ItemInfo.ItemName");

//订单子行.料号

map.Add(ItemInfo_ItemCode, "ItemInfo.ItemCode");

//供应来源

map.Add(SupplySource, "SupplySource");

//供应组织

map.Add(SupplyOrg_Name, "SupplyOrg.Name");

//存储地点

map.Add(WH_Name, "WH.Name");

//承诺日期

map.Add(DeliveryDate, "DeliveryDate");

//数量1

map.Add(ShipPlanQtyTU, "ShipPlanQtyTU");

//数量2

map.Add(ShipPlanQtyTBU, "ShipPlanQtyTBU");

//ID

map.Add(SOLine_ID, "SOLine.ID");

//ID

map.Add(Org_ID, "Org.ID");

//销售单位_精度_精度

map.Add(TU_Round_Precision, "TU.Round.Precision");

//销售单位_精度_舍入类型

map.Add(TU_Round_RoundType, "TU.Round.RoundType");

//销售单位_精度_舍入值

map.Add(TU_Round_RoundValue, "TU.Round.RoundValue");

//销售基准单位_精度_精度

map.Add(TBU_Round_Precision, "TBU.Round.Precision");

//销售基准单位_精度_舍入类型

map.Add(TBU_Round_RoundType, "TBU.Round.RoundType");

//销售基准单位_精度_舍入值

map.Add(TBU_Round_RoundValue, "TBU.Round.RoundValue");

//ID

map.Add(SOLine_SO_ID, "SOLine.SO.ID");

//赛班

map.Add(Seiban_SeibanNO, "Seiban.SeibanNO");

}

}

#endregion

 

使用EntityViewQuery来处理System.Data.DataTable

如果对于一些复杂的查询,不能用一个完整的OQL表达出来,则需要使用临时表的方法,做二次查询,或在DataTable中计算。

可以使用EntityViewQuery来创建和使用临时表。使用该对象之前,需要将连接打开,代码如下:

    IDbConnection sqlCon = DatabaseManager.GetCurrentConnection();

    if (sqlCon.State == ConnectionState.Closed)

    {

        sqlCon.Open();

        DatabaseManager.CurrentConnection = sqlCon;

}

EntityViewQuery viewQuery = new EntityViewQuery();

 

 

如果大家有用EntityDataQuery查询出结果,进行数据处理,然后把数据写到临时表中的这样一个过程,要注意加上以下红色标明的那行代码。否则如果用到多语字段,会把当前系统支持的所有多语记录都查出来。另外如果能用EntityViewQuery ,尽可能的用EntityViewQuery去实现。如下面黄色背景所示:

private void GetProductCostRecordToTable()

{

    EntityDataQuery productQry = CA.CalculateCost.ProductCost.Finder.CreateDataQuery();

    productQry.QOptions.MultiLangOption = new GlobalizationContext(ContextManager.CultureName);

 

    //获取OQL串 

    StringBuilder productoql = new StringBuilder();

    productoql.Append(" ID as ID, ");

    productoql.Append("Org.Name as Org_Name, ");

    productoql.Append("SOB.Name as SOB_Name, ");

    productoql.Append("SOBPeriod.Code as SOBPeriod_Code, ");

    productoql.Append("CostField.Name as CostField_Name, ");

    productoql.Append("CostType.Name as CostType_Name, ");

    productoql.Append("IsBooking as IsBooking, ");

    productoql.Append("Product.Name as Product_Name, ");

    productoql.Append("Cost.OverheadPriorCost as Cost_OverheadPriorCost, Cost.LaborPriorCost as Cost_LaborPriorCost, Cost.MaterialPriorCost as Cost_MaterialPriorCost, Cost.MachinePriorCost as Cost_MachinePriorCost, Cost.OverheadCurrentCost as Cost_OverheadCurrentCost, Cost.MaterialCurrentCost as Cost_MaterialCurrentCost, Cost.MachineCurrentCost as Cost_MachineCurrentCost, Cost.LaborCurrentCost as Cost_LaborCurrentCost, Cost.SubcontractPriorCost as Cost_SubcontractPriorCost, Cost.SubcontractCurrentCost as Cost_SubcontractCurrentCost ");

    productQry.Select(productoql.ToString());

    DataSet ds = productQry.FindDataSet(this.QryOqlWhere);

    AddDataToTable(ds);

}

UI端代码示例

 

Action中代码

主要是定义DTOFullName,使用DTOQueryStrategyImpl来获取CaseModel,使用GridNavigateAction来加载第一页

public partial class SalerOrderSumBQryUIModelAction

{

    public string QryModelID = "2b14cc70-eb35-4ac3-bffa-887f67a0362e";

    string DTOFullName = "UFIDA.U9.SM.SMQueryBP.SOSumBQueryDTO";//定义DTO实体全名

   

    。。。

    。。。

。。。

   

    //输出

    private void OnOutPut_Extend(object sender, UIActionEventArgs e)

    {

        IUFDataGrid UIGrid = this.CurrentPart.GetUFControlByName(this.CurrentPart.TopLevelContainer, "DataGrid1") as IUFDataGrid;

       UFIDA.U9.MO.MO.Proxy.ParentSubMOBQryBPProxy proxy = new UFIDA.U9.MO.MO.Proxy.ParentSubMOBQryBPProxy();

        QryBPExportService qryExportservice = new QryBPExportService(UIGrid, proxy, "QryInParameter", this.CurrentPart.NameValues["MOID"].ToString());

 

        IExportSettings settings = ExportServiceFactory.GetInstance().CreateExportSettingsObject();

        settings.PrintData = qryExportservice.GetResultSet();

        e.Tag = settings;

 

        this.OnOutPut_DefaultImpl(sender, e);

    }

    //打印

    private void OnPrint_Extend(object sender, UIActionEventArgs e)

    {

        IUFDataGrid UIGrid = this.CurrentPart.GetUFControlByName(this.CurrentPart.TopLevelContainer, "DataGrid1") as IUFDataGrid;

       UFIDA.U9.MO.MO.Proxy.ParentSubMOBQryBPProxy proxy = new UFIDA.U9.MO.MO.Proxy.ParentSubMOBQryBPProxy();

        //QryBPExportService构造函数的说明,请参见下文

        QryBPExportService qryExportservice = new QryBPExportService(UIGrid, proxy, "QryInParameter", this.CurrentPart.NameValues["MOID"].ToString());

 

        IExportSettings settings = ExportServiceFactory.GetInstance().CreateExportSettingsObject();

        settings.PrintData = qryExportservice.GetResultSet();

        e.Tag = settings;

 

        this.OnPrint_DefaultImpl(sender, e);

}

//数据加载的扩展

private void this.CurrentPart.GetUFControlByName(this.CurrentPart.TopLevelContainer, "DataGrid1") as IUFDataGrid;

        //使用DTO查询策略

        DTOQueryStrategyImpl dtoQryStrategyImpl = new DTOQueryStrategyImpl(this.CurrentState, DTOFullName, QryModelID,this.MainView, UIGrid);

        dtoQryStrategyImpl.Adjust();

        this.MainView.Clear();

       

        //调用BP,加载第一页的数据

        UFIDA.U9.MO.MO.Proxy.ParentSubMOBQryBPProxy proxy = new UFIDA.U9.MO.MO.Proxy.ParentSubMOBQryBPProxy();

        GridNavigateAction action = new GridNavigateAction(UIGrid, proxy, "QryInParameter");

       

        //如果是消费者画面,则需要处理Webpart关联传入的参数,如下:

        action.FilterOpath = this.CurrentPart.NameValues["MOID"].ToString();

 

        action.LoadFirstPage();

       

        if (this.MainView.Records.Count == 0)

        {

            this.CurrentPart.ShowWindowStatus(UFIDA.U9.UI.PDHelper.PDResource.GetNoRecordSucessInfo());

        }

        else

        {

            this.CurrentPart.ShowWindowStatus(UFIDA.U9.UI.PDHelper.PDResource.GetFindSucessInfo());

        }

    }

 

    public void InitCaseModel()

    {

        QryService.ClearSession((UFSoft.UBF.UI.FormProcess.BaseWebForm)(this.CurrentPart));

        IUFDataGrid UIGrid = this.CurrentPart.GetUFControlByName(this.CurrentPart.TopLevelContainer, "DataGrid1") as IUFDataGrid;

       

        //使用DTO查询策略

        DTOQueryStrategyImpl dtoQryStrategyImpl = new DTOQueryStrategyImpl(this.CurrentState, DTOFullName, QryModelID,this.MainView, UIGrid);

        CaseModel caseModel = dtoQryStrategyImpl.GetQryModel();

       

        QryService.SetCaseModelToSession((UFSoft.UBF.UI.FormProcess.BaseWebForm)(this.CurrentPart), caseModel);

    }

}

 

QryBPExportService构造函数说明

public QryBPExportService(IUFDataGrid grid,object bp, string bpPropertyName,string filterOpath)

grid:查询列表画面中的UIGrid

bp:BP的代理(proxy)

bpPropertyName:设计BP时,“查询BP通用入参DTO”的名称

filterOpath:存放不能通过“查询BP通用入参DTO”来传递的查询条件,比如从其他界面传递过来的参数等。

WebPart中代码

(定义和实现翻页事件)

public void After UpdatePanelUpdateMode.Always; 

 

//this.IsProviding = true;//如果在Webpart关联中,本WebPart是提供者,则需要加入这段话

 

//定义翻页事件,需要加入引用using UFSoft.UBF.UI.WebControlAdapter;

    ((UFWebDataGridAdapter)this.DataGrid1).GridMakePageEventHandler += new GridMakePageDelegate(SOListUIFormWebPart_GridMakePageEventHandler);

}

 

//翻页事件

void SOListUIFormWebPart_GridMakePageEventHandler(object sender, GridMakePageEventArgs e)

{

GridNavigateAction action = new GridNavigateAction(this.DataGrid1, new SOSumBQueryBPProxy(), "QryInParameter");   

//如果是消费者画面,则需要根据情况来处理“关联参数”,即处理action.FilterOpath,如果开发人员自定义了FilterOpath,那么在这里的翻页事件中,也要重新转入

Action.FilterOpath = "某种条件"

 

switch (e.Action)

    {

        case enumPageAction.FirstPage:

            action.FirstPage();

            break;

        case enumPageAction.PreviousPage:

            action.PrevPage();

            break;

        case enumPageAction.NextPage:

            action.NextPage();

            break;

        case enumPageAction.LastPage:

            action.LastPage();

            break;

    }

    this.DataGrid1.PageAction = e.Action;

}

 

public void BeforeUIModelBinding()

{

     //如果条件没能传入到BP中,则是因为没按这个规范来写BeforeUIModelBinding中的代码。[FAQ01]

    if (QryService.IsCallInitCaseModel(this.DataGrid1))

    {

        this.Action.InitCaseModel();

    }

    if (QryService.IsCallAdjust(this.DataGrid1))

    {

        this.Action.QueryAdjust();

    }

    else

    {

        QryService.SetGridWidthToCase(this.CurrentState, FormID, this.DataGrid1);

    }

}

 

public void AfterUIModelBinding()

{

QryService.BindEnum("DDLCase", this, "2b14cc70-eb35-4ac3-bffa-887f67a0362e");

//添加调整UIGrid的代码

}

 

查询开发框架

概述BE查询方式的执行过程根据BE实体的元数据来生成默认的CaseModel用户在查询方案画面中,调整条件、栏目、排序使用BEQueryStrategyImpl将...
点击下载文档
标签: # U9C
分享:
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息