Previous topicNext topic
Help > 开发指南 > 预备知识 >
视图编辑

我们这里讨论的视图编辑,本质上就是指的是通过各种方式加载到表中的数据,该如何编辑、保存到数据库中。我们知道,通常情况下,我们针对一些不包含主键的基础表、视图、存储过程返回的表数据等等,如果想实现可编辑模式的加载与保存的话,往往会得到一句“对于不返回任何键列信息的selectCommand,不支持UpdateCommand 的动态SQL生成。”错误提示。

我们首先得理解,为什么我们可以实现带有主键的基础表的编辑与保存?那是因为微软帮我们做了大量的自动化工作。他会根据数据加载时从数据库中得到的数据结构(Schema)判断当前DataTable中是否包含主键,如果不包含主键,就会抛出上面提到的“对于不返回任何键列信息的selectCommand,不支持UpdateCommand 的动态SQL生成。”错误信息,如果包含主键,他就会自动地帮我们生成一行行依据主键的增、删、改的SQL语句,最后执行这些SQL语句来实现数据的新增、修改与保存。

ExecuteDataTableHelp(SQLString,FillSchema,fillData,UseIndependenceConnection)

在我们数据加载过程中,FillSchema就是控制当前SQL语句是否加载主键的,只有数据库中带有主键的基础表才可以设置为True,在数据加载时就直接填充入数据结构,其他任何形式的加载,比如我们在数据加载里面介绍到的除基础表加载外的其他加载都是只能先设置为False,不加载数据结构。如果仍然想编辑的话,可以在后续表加载到了内存后,再设置一下DataTableHelp.EditDatatableName。

我们在功能概览里面有介绍过视图编辑的一些信息,里面强调了如果想要实现视图的编辑保存功能就必须满足以下几个条件。

1、必须包含唯一不重复的主键。

2、我们只能编辑与保存视图中包含主键的那个主表中的数据。

3、必须指定要视图对应的包含主键的那个主表名称。

那么我们为什么要限制这些条件呢?因为只有满足了这些条件了,我们才有可能动态地去生成自动更新的SQL语句,才能实现保存。第一条,要求必须包含唯一不重复的主键。那是因为只有这样的表才是基础表与其他关系表一一对应的场景,如果是一对多的场景就无法符合常规的编辑保存的概念了;第二条,只能编辑与保存视图中包含主键的那个主表中的数据。那是因为我们动态生成的SQL更新语句就是基于基础表来进行的,超过基础表范围外的字段根本不会在动态生成的SQL语句内;第三条,必须指定要视图对应的包含主键的那个主表名称。这个也是最基础中的基础。因为没有了明确的指定,我们就不知道应该基于哪个表生成相应的SQL语句了。

所以,你们看,只要满足我们能够动态生成更新SQL语句的条件的话,任何表都是可以编辑与保存的。这样子说来,无论是数据库视图、平台内视图、手写SQL语句、存储过程等等等等,只要你加载进来的数据符合我们上面提到的条件,在数据加载后指定一下DataTableHelp.EditDatatableName属性为相对应的基础表名,则可以实现常规的编辑与保存了。

主表使用视图编辑

我们只需要在“视图编辑表”中填充包含主键的基础表名。主表的数据加载,我们可以参考数据加载。如果是非基础表想要实现编辑保存的功能,就需要先设置“是否视图查询”为True,然后再设置“视图编辑表”。

子表使用视图编辑

我们需要让子表也实现视图编辑的话,需要在主表的表属性中,设置子表关联时,勾选子表的“视图查询”选项,然后再在子表对应行“编辑数据库表名”中填充包含主键的基础表名。

代码中实现视图编辑

我们平时在写代码时,也可以直接根据条件来写一些保存视图数据的功能来。

Vb.Net
Dim db As Database=Proj.SysDataFactory("UserDB")
'因为我们加载的是视图,所以第二个参数必须设置为False
Dim dt As DataTableHelp=db.ExecuteDataTableHelp("select * from vwEmployee Where EmployeeID='U000000004'",False,True)
If dt IsNot Nothing AndAlso dt.DataRows.Count>0 Then
    Dim dr As RowData=dt.DataRows(0)
    dr("Age")=45
    '第一种方法:保存视图时必须指定基础表
    dt.SaveView("EmployeeInfo")
    '直接从数据库查询保存结果
    Proj.MsgDebug.Add(db.ExecuteScalar("select Age from EmployeeInfo where EmployeeID='U000000004'"))
    
    '第二种保存视图的方法
    dt.EditDatatableName="EmployeeInfo" '先指定可基础表名
    dr("Age")=56
    dt.Save() '直接保存
    '直接从数据库查询保存结果
    Proj.MsgDebug.Add(db.ExecuteScalar("select Age from EmployeeInfo where EmployeeID='U000000004'"))
End If

'返回结果:45
'返回结果:56

C#
Database db = Proj.SysDataFactory["UserDB"];
// 因为我们加载的是视图,所以第二个参数必须设置为False
DataTableHelp dt = db.ExecuteDataTableHelp("select * from vwEmployee Where EmployeeID='U000000004'", false, true);
if (dt != null && dt.DataRows.Count > 0)
{
    RowData dr = dt.DataRows[0];
    dr["Age"] = 45;
    // 第一种方法:保存视图时必须指定基础表
    dt.SaveView("EmployeeInfo");
    // 直接从数据库查询保存结果
    Proj.MsgDebug.Add(db.ExecuteScalar("select Age from EmployeeInfo where EmployeeID='U000000004'"));
    
    // 第二种保存视图的方法
    dt.EditDatatableName = "EmployeeInfo"; // 先指定可基础表名
    dr["Age"] = 56;
    dt.Save(); // 直接保存
    // 直接从数据库查询保存结果
    Proj.MsgDebug.Add(db.ExecuteScalar("select Age from EmployeeInfo where EmployeeID='U000000004'"));
}

// 返回结果:45
// 返回结果:56