使用代码执行与数据相关的任务

您可以使用 Visual Studio LightSwitch 中的设计器和工具窗口,完成许多与数据相关的设计任务。 但是,某些任务仅可通过将代码添加到应用程序中才能完成。 例如,若要通过应用自定义条件来验证字段,必须编写代码。 本文档演示如何通过使用数据运行时对象模型来完成与数据相关的任务。 有关可以在应用程序中编写代码的位置的更多信息,请参见以下主题:

有关如何使用 Visual Studio LightSwitch 编写代码的一般指南,请参见 在 LightSwitch 中编写代码

常规任务

下面的列表显示了与常见数据相关的任务,您可以通过使用数据运行时对象模型来完成。 本文档稍后会介绍这些任务。

  • 读取数据

  • 更新数据

  • 删除数据

  • 添加数据

  • 保存数据

  • 验证数据

  • 设置数据权限

  • 使用变更集

  • 扩展查询

读取数据

您可以从您的应用程序中的任何数据源读取各个数据项或数据项的集合。

下面的示例检索屏幕中当前选定的客户。

Private Sub RetrieveCustomer_Execute()
    Dim cust As Customer = Me.Customers.SelectedItem
    If cust.ContactName = "Bob" Then
        'Perform some task on the customer entity.
    End If
End Sub
partial void RetrieveCustomer_Execute()
{
    Customer cust = this.Customers.SelectedItem;
    if (cust.ContactName == "Bob")
    {
        //Perform some task on the customer entity.
    }
}

下面的示例循环访问客户的集合。

Private Sub RetrieveCustomers_Execute()
    For Each cust As Customer In Me.DataWorkspace.NorthwindData.Customers
        If cust.ContactName = "Bob" Then
            'Perform some task on the customer entity.
        End If
    Next

End Sub
partial void RetrieveCustomers_Execute()
{
    foreach (Customer cust in this.DataWorkspace.NorthwindData.Customers)
    {
        if (cust.ContactName == "Bob")
        {
            //Perform some task on the customer entity.
        }
    }
}

Ff851990.collapse_all(zh-cn,VS.110).gif导航数据关系

您可以从相关的实体读取数据。 例如,客户实体可能与订单实体具有一对多的关系。 您可以通过使用额、客户实体的**“订单”**属性,循环访问客户已下的所有订单。

下面的示例循环访问与客户有关的订单集合。

Private Sub RetrieveSalesOrders_Execute()
    Dim cust As Customer = Me.Customers.SelectedItem
    For Each myOrder As Order In cust.Orders
        If myOrder.OrderDate = Today Then
            'Perform some task on the order entity.
        End If
    Next
End Sub
partial void RetrieveSalesOrders_Execute()
{
    Customer cust = this.Customers.SelectedItem;

    foreach (Order order in cust.Orders)
    {
        if (order.OrderDate == DateTime.Today)
        {
            //perform some task on the order entity.
        }
    }
}

下面的示例获取下了特定订单的客户。

Private Sub RetrieveCustomer_Execute()
    Dim order As Order
    order = Me.DataWorkspace.NorthwindData.Orders_Single _
        (Orders.SelectedItem.OrderID)
    Dim cust As Customer
    cust = order.Customer
    'Perform some task on the order entity.
End Sub
partial void RetrieveCustomer_Execute()
{
    Order order = this.DataWorkspace.NorthwindData.Orders_Single
        (Orders.SelectedItem.OrderID);

    Customer cust = order.Customer;
    //Perform some task on the customer entity.

}

Ff851990.collapse_all(zh-cn,VS.110).gif通过执行查询读取数据

您可以从模型中检索查询,然后使用代码执行这些查询。 若要查看示例,请参见如何:使用代码从查询检索数据

更新数据

您可以通过使用代码更新任何实体的数据。 下面的示例演示了当用户在屏幕的订单实体中创建订单,然后单击**“保存”**按钮时运行的代码。 该代码通过使用订单详细信息实体中的字段更新产品实体中的字段。

Private Sub Orders_Inserting(entity As Order)
    For Each detail In entity.Order_Details
        detail.Product.UnitsInStock =
            detail.Product.UnitsInStock - detail.Quantity
    Next
End Sub
partial void Orders_Inserting(Order entity)
{
    foreach (Order_Detail detail in entity.Order_Details)
    {
        detail.Product.UnitsInStock = 
            (short?)(detail.Product.UnitsInStock - detail.Quantity);
    }
}

备注

如果您的代码修改了其他数据源的数据,则必须通过调用该数据源的 SaveChanges 方法,提交这些更改。有关更多信息,请参见 How to: Save Data

删除数据

您可以通过调用任何实体的 Delete 方法删除数据。 下面的示例将客户从 NorthwindDate 数据源中删除。

Private Sub DeleteCustomer_Execute()
    Dim cust As Customer
    cust = Me.Customers.SelectedItem
    If Customers.CanDelete Then
        cust.Delete()
    End If

End Sub
partial void DeleteCustomer_Execute()
{
    Customer cust =
        this.Customers.SelectedItem;

    if (Customers.CanDelete)
    {
        cust.Delete();
    }
}

添加数据

下面的示例将新客户添加到 NorthwindData 数据源。 本示例将使用最近添加到 SharePoint 列表中的联系人信息填充描述新客户的字段。 该示例调用名为 NewCustomersInSharePoint 的查询,以确定 SharePoint 列表中哪些联系人尚未导入到 NorthwindData 数据源。

Private Sub ImportCustomers_Execute()
    For Each spCust As SharePointCustomer In _
        Me.DataWorkspace.SharePointData.NewCustomersInSharePoint
        Dim newCust As Customer = New Customer()
        With newCust

            .ContactName = spCust.FirstName & " " & spCust.LastName
            .Address = spCust.Address
            .City = spCust.City
            .PostalCode = spCust.PostalCode
            .Region = spCust.Region

            'Set the CopiedToDatabase field of the item in SharePoint.
            spCust.CopiedToDatabase = "Yes"
        End With

    Next
    Me.DataWorkspace.SharePointData.SaveChanges()



End Sub
partial void ImportCustomers_Execute()
{
    foreach (SharePointCustomer spCust in
this.DataWorkspace.SharePointData.NewCustomersInSharePoint())
    {
        Customer newCust = new Customer();

        newCust.ContactName = spCust.FirstName + " " + spCust.LastName;
        newCust.Address = spCust.Address;
        newCust.City = spCust.City;
        newCust.PostalCode = spCust.PostalCode;
        newCust.Region = spCust.Region;

        //Set the CopiedToDatabase field of the item in SharePoint.
        spCust.CopiedToDatabase = "Yes";
    }
    this.DataWorkspace.SharePointData.SaveChanges();


}

保存数据

通常情况下,挂起的更改会在用户单击屏幕中的**“保存”**按钮时提交到数据源。 但是,您也可以通过添加调用数据源的 SaveChanges 方法的代码,提交挂起的更改。 如果您要完成这些任务,必须添加此代码:

  • 提交对位于其他数据源中的数据所做的更改。

  • 重写屏幕的 Save 事件。

Ff851990.collapse_all(zh-cn,VS.110).gif提交对位于其他数据源中的数据所做的更改

您在其中编写自定义代码的文件有一个主数据源。 如果您添加可修改您的 LightSwitch 解决方案中另一个数据源中数据的自定义代码,则必须通过调用该数据源的 SaveChanges 方法,提交这些更改。

下面的示例演示了当用户在屏幕的订单实体中创建订单,然后单击**“保存”**按钮时运行的代码。 该代码通过使用订单详细信息实体中的字段更新产品实体中的字段。 因为产品实体位于另一个数据源,所以此代码将调用该数据源的 SaveChanges 方法以提交更改。

Private Sub Orders_Inserting(entity As Order1)
    For Each detail In entity.Order_Details
        detail.Product.UnitsInStock = detail.Product.UnitsInStock - detail.Quantity
    Next
    Me.DataWorkspace.ProductDataSource.SaveChanges()

End Sub
partial void Orders_Inserting(Order1 entity)
{
    foreach (Order_Detail1 detail in entity.Order_Details)
    {
        detail.Product.UnitsInStock = (short?)
            (detail.Product.UnitsInStock - detail.Quantity);
    }
    this.DataWorkspace.ProductDataSource.SaveChanges();

}

Ff851990.collapse_all(zh-cn,VS.110).gif重写屏幕的保存事件

您可以通过重写 Save 事件,更改**“保存”按钮在屏幕上的行为。 因为您正在替换“保存”**按钮的行为,所以当您要提交挂起的更改时,您的代码必须调用 SaveChanges 方法。

下面的示例重写客户屏幕的 Save 事件,以捕获并处理当保存操作失败时可能会被抛出的特定异常。

Private Sub CustomersListDetail_Saving(ByRef handled As Boolean)
    Try
        Me.DataWorkspace.SharePointData.SaveChanges()

    Catch ex As DataServiceOperationException

        If ex.ErrorInfo = "DTSException" Then
            Me.ShowMessageBox(ex.Message)
        Else
            Throw ex

        End If

    End Try

    handled = True


End Sub
partial void CustomersListDetail_Saving(ref bool handled)
{
    try
    {
        this.DataWorkspace.SharePointData.SaveChanges();
    }
    catch (DataServiceOperationException ex)
    {
        if (ex.ErrorInfo == "DTSException")
        {
            this.ShowMessageBox(ex.Message);
        }
        else
        {
            throw ex;
        }
    }
    handled = true;


}

验证数据

您可以将自定义验证规则应用到实体的字段。 您可以添加当用户以不符合您的验证规则的方式修改属性值时显示的自定义错误消息。 有关更多信息,请参见如何:验证数据

设置数据权限

默认情况下,所有用户都可以查看、插入、删除或更新出现在屏幕中的数据。 但是,您可以通过将代码添加到下列方法之一,以限制这些权限:

  • CanRead

  • CanInsert

  • CanDelete

  • CanUpdate

如果您通过使用这些方法限制操作,则 LightSwitch 会使不具有不受限制的权限的用户无法操作。 有关更多信息,请参见 如何:处理数据事件

下面的示例使用户能够更新客户信息,如果该用户具有更新权限。 此代码示例要求名为 RoleUpdate 的权限组。 有关如何将权限组添加到应用程序的更多信息,请参见 启用授权和创建权限

Private Sub Customers_CanUpdate(ByRef result As Boolean)
    result = Me.Application.User.HasPermission(Permissions.RoleUpdate)
End Sub
partial void Customers_CanUpdate(ref bool result)
{
    result = this.Application.User.HasPermission(Permissions.RoleUpdate);
}

默认情况下,LightSwitch 会在用户尝试查看、插入、删除或更新信息时调用这些方法。 您还可以在读取或修改数据之前,在您的自定义代码中调用这些方法。

使用变更集

您可以识别并在将更改提交到数据源之前放弃挂起的更改。 下面的示例演示了识别并放弃所挂起更改的三个用户方法。 UndoAllCustomerUpdates 方法会放弃对所有客户所做的所有更改。 UndoAllUpdates 方法会放弃对数据源所做的所有更改。 UndoCustomerEdit 方法会放弃对客户屏幕中当前选定的数据行所做的更改。

Private Sub UndoAllCustomerUpdates_Execute()
    For Each Cust As Customer In _
        Me.DataWorkspace.NorthwindData.Details. _
        GetChanges().OfType(Of Customer)()

        Cust.Details.DiscardChanges()

    Next
End Sub

Private Sub UndoAllUpdates_Execute()
    Me.DataWorkspace.NorthwindData.Details.DiscardChanges()
End Sub

Private Sub UnduCustomerEdit_Execute()
    Customers.SelectedItem.Details.DiscardChanges()
End Sub
partial void UndoAllCustomerUpdates_Execute()
{
    foreach (Customer cust in 
        this.DataWorkspace.NorthwindData.Details.
        GetChanges().OfType<Customer>())
    {
        cust.Details.DiscardChanges();
    }
}

partial void UndoAllUpdates_Execute()
{
    this.DataWorkspace.NorthwindData.Details.DiscardChanges();
}

partial void UndoCustomerEdit_Execute()
{
    Customers.SelectedItem.Details.DiscardChanges();
}

扩展模型化的查询

如果您要修改超出查询设计器能力的查询,您可以通过将代码添加到查询的 PreProcessQuery 方法来扩展查询。 有关更多信息,请参见 如何:使用代码扩展查询

请参见

概念

在 LightSwitch 中编写代码