65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 ADO.NET 数据服务在 Silverlight 中执行 CRUD 操作

2008 年 2 月 11 日

CPOL

8分钟阅读

viewsIcon

120303

downloadIcon

803

使用 ADO.NET 数据服务(Astoria)在 Silverlight 中执行 CRUD(创建、检索、更新、删除)操作的最简单方法。

引言

本文介绍了使用 ADO.NET 数据服务(Astoria)在 Silverlight 中执行 CRUD(创建、检索、更新、删除)操作的最简单方法。在 Silverlight 中与数据库通信有两种方式

  1. Web服务
  2. ADO.NET 数据服务

我选择 ADO.NET 数据服务用于本文,因为 RESTful 服务和 RIA(富互联网应用程序)开发是最佳匹配。如果您不了解 ADO.NET,请阅读我的上一篇文章 这里

目录

  • 必备组件
  • 在 SQL 2005 中创建数据库
  • 在 Visual Studio 2008 中创建 ADO.NET 数据服务
  • 为 Silverlight 项目创建 Astoria 代理
  • 在 Silverlight 中插入新记录
  • 在 Silverlight 中更新现有记录
  • 在 Silverlight 中从数据库检索记录
  • 在 Silverlight 中删除记录
  • 结论
  • 常见问题解答

必备组件

在 SQL 2005 中创建数据库

注意:如果您已经知道如何在 SQL 2005 中创建数据库,请跳过并跳转到下一节。

步骤 1:打开 SQL Server Management Studio Express

SQL Server Management Studio Express - FREE edition

步骤 2:连接到您已安装在本地计算机上的 SQL Server

Connect to Server

步骤 3:在对象资源管理器中右键单击“数据库”节点,然后选择“新建数据库”

New Database - SQL 2005

步骤 4:输入您的数据库名称(在此示例中我将其命名为“MyStore”)然后单击“确定”按钮

create-new-database-small.jpg

步骤 5:右键单击您创建的数据库的“表”节点,然后选择“新建表”

New Table

步骤 5:创建名为“ProductID(INT Identity PK)”和“ProductName”的两个列。将表命名为“Products”

Structure of Products Table

好的。以上就是关于在 SQL 2005 中创建新表的内容。

在 Visual Studio 2008 中创建 ADO.NET 数据服务

注意:我在之前的文章“从 Silverlight 使用 ADO.NET 数据服务(Astoria)”中已经解释了如何创建 ADO.NET 数据服务。(在此示例中我将使用 ASP.NET 3.5 扩展 Web 应用程序)。如果您已经阅读过这篇文章,请跳过本节。

步骤 1:创建新的 ASP.NET 3.5 扩展 Web 应用程序

  • 单击“新建项目”图标或按“Ctrl+Shift+N”。
  • 选择“ASP.NET Web 应用程序”并将应用程序命名为“CRUDSilverlight”。
  • 单击“确定”按钮。

VS 2008 - New ASP.NET 3.5 Extensions Web Application

步骤 2:创建“ADO.NET Entity Data Model”

创建新的 ASP.NET 3.5 扩展项目后,您需要将“ADO.NET Entity Data Model”添加到您的项目中。您需要从 SQL 2005 中创建的表中生成数据模型。如果您想查看添加 ADO.NET Entity Data Model 的所有截图,请在这篇文章中查看“创建 ADO.NET Entity Data Model”。

Products Data Model

步骤 3:创建“ADO.NET 数据服务”

添加 ADO.NET Entity Data Model 后,您需要将“ADO.NET 数据服务”添加到您的项目中。然后,您需要在第一行放置数据源类名,并取消注释 InitializeService() 函数中的“config.SetResourceContainerAccessRule("MyEntityset", ResourceContainerRights.AllRead);”。将“MyEntityset”替换为“*”,并将“AllRead”更改为“All”。

public class WebDataService1 : WebDataService<MyStoreModel.MyStoreEntities>
{

    // This method is called once during service initialization to allow
    // service-specific policies to be set
    public static void InitializeService(IWebDataServiceConfiguration config)
    {

        // TODO: set rules to indicate which entity sets and service operations are
        // visible, updatable, etc.
        // (for testing purposes use "*" to indicate all entity sets/service
        // operations, but that option should NOT be used in production systems)

        // Example for entity sets (this example uses
        // "AllRead" which allows reads but not writes)
        config.SetResourceContainerAccessRule("*", ResourceContainerRights.All);


        // Example for service operations
        //config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
    } 

    // Query interceptors, change interceptors and service operations go here
}

步骤 4:将自动分配的端口更改为您 Web 应用程序的特定端口

请注意,此步骤非常重要。我们应该使用静态端口以防止跨域问题。Web 选项卡位于项目的属性窗口下。

Change the auto-assign port to specific port of your web application

为 Silverlight 项目创建 Astoria 代理

当我撰写关于“如何在 Silverlight 中使用 ADO.NET 数据服务”时,我没有使用 Webdatagen.exe 为 Astoria 生成代理类。Bryant 在这篇文章中指出了生成代理类的方法。(非常感谢 Bryant)因此,我们可以节省在 Silverlight 项目和 ASP.NET Web 项目之间复制代码的时间。

  • 转到“Visual Studio 2008 命令提示符”。(注意:如果您使用的是 Windows Vista,则必须以管理员权限运行命令行。右键单击菜单并选择“以管理员身份运行”。否则,Webdatagen.exe 将无法在磁盘上写入生成的文件。)
  • 转到“C:\Program Files\Microsoft ASP.NET 3.5 Extensions>”文件夹。
  • 在命令行中输入以下命令
  • "WebDataGen.exe /mode:ClientClassGeneration
    /outobjectlayer:Products.cs
    /uri:https://:52799/WebDataService1.svc"

    Products.cs 是我们要生成的代理文件的名称。https://:52799/WebDataService1.svc 是 ADO.NET 数据服务的 URL。

Making Astoria Proxy for Silverlight project

现在,检查 Microsoft ASP.NET 3.5 Extensions 下的 Products.cs。您可以将此代理文件添加到 Silverlight 项目中。

好的。我们已经完成了使用 ADO.NET 数据服务在 Silverlight 中执行 CRUD 操作的准备工作。让我们看看如何执行这些操作。

在 Silverlight 中插入新记录

您可以创建一个 Products 对象的实例,并根据需要设置产品名称。由于产品 ID 是标识字段,因此我们无需指定。由于我们要添加数据,因此会将 MergeOption 设置为 AppendOnly

try{

    MyStoreModel.Products _products = new MyStoreModel.Products();
    _products.ProductName = "Windows Vista";

    MyStoreModel.MyStoreEntities _mystore = 
       new MyStoreModel.MyStoreEntities(_serviceUriString);
    _mystore.MergeOption = Microsoft.Data.WebClient.MergeOption.AppendOnly;
    _mystore.AddObject("Products", _products);
    _mystore.SaveChanges();

    insertTextBlock.Text = "New record has been added successfully." + 
                           " Please check Products table in SQL";
}
catch(Exception ex){
   throw ex;
}

在 Silverlight 中更新现有记录

下面的代码用于更新数据库中的现有记录。我们将使用“OverwriteChangesMergeOption 进行更新。

try{

    MyStoreModel.MyStoreEntities _mystore = 
      new MyStoreModel.MyStoreEntities(_serviceUriString);
    _mystore.MergeOption = 
      Microsoft.Data.WebClient.MergeOption.OverwriteChanges;


    MyStoreModel.Products _products = new MyStoreModel.Products();
    _products.ProductID = 1;
    _products.ProductName = "Visual Studio 2008 Professional";

    _mystore.AttachObject("Products", _products);
    _mystore.UpdateObject(_products);
    updateTextBlock.Text = "ProductID(#1) has been updated successfully." + 
                           " Please check Products table in SQL";

    _mystore.SaveChanges();

}
catch (Exception ex) {
    Console.WriteLine(ex.Message);
}

注意:Astoria 的 ReadMe.txt 中写道:

更新(调用 UpdateObject 后跟 SaveChanges 方法)即使操作在服务器端成功,也可能返回异常。

所以,您在更新记录时会遇到异常,但不用担心。即使出现异常,您的记录也会在 SQL 数据库中更新。这是一个已知问题,将在下一个版本中修复。

在 Silverlight 中从数据库检索记录

以下代码用于从数据库检索记录。您还可以参考我博客上的文章:“使用 ADO.NET 数据服务”。

try {


    MyStoreModel.MyStoreEntities _mystore = 
       new MyStoreModel.MyStoreEntities(_serviceUriString);
    _mystore.MergeOption = Microsoft.Data.WebClient.MergeOption.OverwriteChanges;

    Microsoft.Data.WebClient.WebDataQuery<MyStoreModel.Products>
    products = _mystore.CreateQuery<MyStoreModel.Products>(
               "/Products?$orderby=ProductID");

    double top=0;

    foreach (MyStoreModel.Products p in products) {
          TextBlock tbk = new TextBlock();
          tbk.Text = p.ProductName;
    
          tbk.Height = 50;
    
          top += tbk.Height;
    
          tbk.SetValue(TopProperty, top);
    
          view.Children.Add(tbk);
    }
}

catch (Exception ex) {
   Console.WriteLine(ex.Message);
}

在 Silverlight 中删除记录

try{

    MyStoreModel.MyStoreEntities _mystore = 
       new MyStoreModel.MyStoreEntities(_serviceUriString);
    _mystore.MergeOption = Microsoft.Data.WebClient.MergeOption.OverwriteChanges;

    MyStoreModel.Products _products = 
       new MyStoreModel.Products();
    _products.ProductID = 1;

    _mystore.AttachObject("Products", _products);
    _mystore.DeleteObject(_products);
    _mystore.SaveChanges();

    deleteTextBlock.Text = "ProductID(#1) has been deleted " + 
               "successfully. Please check Products table in SQL";
}
catch (Exception ex) {
  Console.WriteLine(ex.Message);
}

将配置存储在 XML 中

由于 Silverlight 项目中没有设置或 web.config,我选择使用 XML 文件存储配置信息。但我认为在实际项目中将扩展名更改为 config 会更好。在此示例中,我将服务 URI 存储在 Configs.xml 文件中。

<?xml version="1.0" encoding="utf-8" ?>
<ServiceUriString>https://:52799/WebDataService1.svc</ServiceUriString>

由于我不想使用 WebRequest 加载此 XML,因此我将其嵌入到项目中。以下代码用于在 Silverlight 中读取 XML 文件

Stream stream = this.GetType().Assembly.GetManifestResourceStream(
                "SilverlightProject1.Configs.xml");
XmlReader reader = XmlReader.Create(stream);
while (reader.Read()) {
  if (reader.IsStartElement()) {
    if ("ServiceUriString" == reader.LocalName) {
       reader.Read();
       string _serviceURL = reader.Value;
       reader = null;
       stream.Dispose();
       return _serviceURL;
    }
  }
} 

reader = null;
stream.Dispose();

return string.Empty;

结论

这就是在 Silverlight 中执行 CRUD 操作的所有内容。抱歉,我的示例中没有漂亮的 UI。由于本文专注于 CRUD 操作,因此我不想在示例中添加复杂的 UI 代码。希望您觉得有用,如果您有任何意见或建议,请随时告诉我。谢谢。

常见问题解答

  1. 我在从数据库检索记录时遇到了这个异常“根级别的 DTD 出现无效字符。行 1,位置 1”。为什么?
  2. 数据服务的 UriString 错误。请检查您是否有任何拼写错误。另外,UriString 是区分大小写的。

  3. 我在更新记录时遇到这个异常“由于对象的当前状态,操作无效”。为什么?
  4. 正如我在“更新记录”部分所写,这是一个已知问题,将在下一个版本中修复。您的记录将在数据库中更新,但您会遇到异常。只需忽略该异常。

  5. “无法更新 EntitySet 'Products',因为它具有 DefiningQuery 且在 <ModificationFunctionMapping> 元素中不存在支持当前操作的 <InsertFunction> 元素”
  6. 只需删除项目中的 Entity Model,然后重新创建新的。我在创建此示例时遇到了这个问题。我所做的是,我在 VS 中创建了 Entity Model,而没有在 Products 表中创建主键。当我尝试插入新记录时,我收到了这个错误。因此,我删除了 Entity Model 并重新创建了它。这将解决问题。我认为还有其他更好的方法可以做到这一点,但我不知道。如果有人能告诉我方法,那就太好了。

  7. 我正在尝试使用 WebDataGen.exe 生成代理类,但即使命令行中没有显示错误,也没有生成任何文件。
  8. 如果您是 Windows Vista 用户,则启动命令行时需要以管理员身份运行。

  9. 您将服务 URL 存储在 Silverlight 项目的哪里?
  10. 由于没有设置或 web.config,我将连接字符串存储在 Configs.xml 中,该文件在 Silverlight 中设置为“嵌入的资源”。有一个名为“Configs.cs”的类,它将从该 XML 文件读取服务 URL 字符串。

  11. 我还有其他未包含在 FAQ 中的问题。如何联系您?
  12. 如果您有任何问题或建议,可以在这篇博文中发表评论。我总是阅读所有评论,并会尽快回复。

相关帖子 ~

© . All rights reserved.