构建基于Azure和SQL Server的新闻展示应用

在MIX09大会上,Nigel Ellis提到了即将到来的新功能:开发者很快就能开发Azure托管的应用,并且可以使用传统的Transact SQL作为后端。虽然这项功能在本文撰写时尚未推出,但可以利用本地Azure开发环境来托管应用,并将其指向本地SQL Server实例,直到能够在线托管为止。

在开发这个应用的过程中,遇到了一些挑战,有的是因为Azure还处于测试阶段,有的则不是。将展示如何编写一个小型应用来展示新闻项目,这些新闻项目会不断更新。后端是一个SQL数据库,定期由Azure Worker Role更新,然后由Silverlight应用程序调用的Web服务读取,该应用程序本身托管在Azure WebRole上。

在开发这个应用时,将从后端开始,一直到构成客户端端的Silverlight应用程序。

创建数据库

根据SQL Data Services会议,无论是本地还是从SQL Data Services访问数据库,都将通过SQL Management Studio进行。一旦数据库创建完成,接下来就是创建存储新闻详情的表。

这个项目实际上是正在创建的一个更大项目的一部分。因此,想使用模式来逻辑上分隔数据库的不同部分。例如,这将允许一个数据库有两个名为'ledger'的表——一个在名为'Sales'的模式中,另一个在名为'Purchases'的模式中。将注意到,以下T/SQL示例中创建的所有数据库对象都以'NewsMashup'这个词开头。要创建这个模式,请对SQL数据库执行以下代码:

CREATE SCHEMA [NewsMashup] AUTHORIZATION [dbo];

创建一个表来存储将从中获取信息源的网站——这允许存储指向父站点的超链接。

创建一个表来存储从中获取新闻详情的信息源:

SET ANSI_NULLS ON; GO SET QUOTED_IDENTIFIER ON; GO SET ANSI_PADDING ON; GO CREATE TABLE [NewsMashup].[Feeds]( [Id] [bigint] IDENTITY(1,1) NOT NULL, [Url] [varchar](max) COLLATE Latin1_General_CI_AS NOT NULL, [Supplier] [bigint] NULL, CONSTRAINT [PK_NewsFeeds] PRIMARY KEY CLUSTERED ( [Id] ASC ) WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING OFF; GO ALTER TABLE [NewsMashup].[Feeds] WITH CHECK ADD CONSTRAINT [FK_NewsFeeds_Supplier] FOREIGN KEY ([Supplier]) REFERENCES [NewsMashup].[Supplier] ([Id]); GO ALTER TABLE [NewsMashup].[Feeds] CHECK CONSTRAINT [FK_NewsFeeds_Supplier];

创建一个表来存储抓取到的新闻:

SET ANSI_NULLS ON; GO SET QUOTED_IDENTIFIER ON; GO SET ANSI_PADDING ON; GO CREATE TABLE [NewsMashup].[Stories]( [Id] [bigint] NOT NULL, [Headline] [varchar](max) COLLATE Latin1_General_CI_AS NOT NULL, [Description] [varchar](max) COLLATE Latin1_General_CI_AS NOT NULL, [Url] [varchar](max) COLLATE Latin1_General_CI_AS NOT NULL, [Supplier] [bigint] NOT NULL ) ON [PRIMARY] GO SET ANSI_PADDING OFF;

创建存储过程以访问和写入数据

将所有数据库查询放在存储过程中,可以获得许多优势。存储过程可以比内联代码更快,部分原因是数据库能够部分编译和优化查询。对于内联代码,这发生在执行时。对于显示新闻标题的应用程序,有四个存储过程;第一个是创建新闻:

ALTER PROCEDURE [NewsMashup].[CreateStory] @Headline VarChar(Max), @Description VarChar(Max), @Url VarChar(Max), @Supplier BigInt, @PubDateValue BigInt AS Begin Declare @Counter BigInt Set @Counter = ( Select Count(*) As PreviousCounter From NewsMashup.Stories Where Url = @Url ) If @Counter = 0 Begin INSERT INTO NewsMashup.Stories (Headline, Description, Url, Supplier, Id) VALUES (@Headline, @Description, @Url, @Supplier, @PubDateValue) End End

这个函数相当简单。首先检查链接是否已经添加到数据库中。如果没有,则添加新闻。接下来的两个过程都涉及到检索标题;需要两个——一个用于从数据库中检索最新的10个标题,另一个检索可能已经添加到数据库中的任何后续标题。这允许新标题在被获取时立即添加到显示中。

检索最新的10个标题:

ALTER PROCEDURE [NewsMashup].[RetrieveHeadlines] AS BEGIN SET NOCOUNT ON; SELECT TOP (10) NewsMashup.Stories.Id, NewsMashup.Stories.Headline, NewsMashup.Stories.Description, NewsMashup.Stories.Url, NewsMashup.Supplier.HasDescription, NewsMashup.Supplier.Name AS Supplier FROM NewsMashup.Stories INNER JOIN NewsMashup.Supplier ON NewsMashup.Stories.Supplier = NewsMashup.Supplier.Id ORDER BY NewsMashup.Stories.Id DESC END

检索最新的新闻标题:

ALTER PROCEDURE [NewsMashup].[RetrieveHeadlines2] @LatestHeadline BigInt AS BEGIN SET NOCOUNT ON; SELECT Id, Headline, Description, Url, Supplier FROM NewsMashup.Stories WHERE (Id > @LatestHeadline) ORDER BY Id END ALTER PROCEDURE [NewsMashup].[RetrieveNewsFeeds] AS Begin Select NewsMashup.Supplier.Id AS Supplier, NewsMashup.Supplier.Name, NewsMashup.Supplier.Url AS HomePage, NewsMashup.Feeds.Url From NewsMashup.Feeds INNER JOIN NewsMashup.Supplier ON NewsMashup.Feeds.Supplier = NewsMashup.Supplier.Id Order By NewsMashup.Supplier.Name End
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485