Este artigo foi traduzido por máquina.

Serviços de dados

Acessar os dados no local ou na nuvem com serviços de dados ADO.NET

Elisa Flasko

Download do código disponível na Galeria de código do MSDN
Procure o código on-line

Este artigo se baseia em versões de pré-lançamento do Windows Azure e MVC do ASP.NET.

Este artigo discute:

  • Windows Azure
  • ASP.NET MVC
  • Windows Azure tabela
  • Desenvolvimento de aplicativo de nuvem vs em local
Este artigo usa as seguintes tecnologias:
Windows Azure, MVC do ASP.NET

Conteúdo

O aplicativo
Consumir um serviço de dados em locais com a biblioteca de cliente de serviços dados ADO.NET
Consultando dados
Criar, atualização e excluir
Consumir um serviço de dados de tabela Azure
O modelo de dados de tabela Azure
Biblioteca de cliente de serviços de dados do ADO.NET
Definir o modelo no cliente
Criar uma tabela
Consultando dados
Criar, atualização e excluir
Soma para cima

serviços da web tem sido um tópico ativo para um número de anos agora, mas o quê, você pode se perguntando, são desses serviços de dados todo mundo está falando recentemente? Como a arquitetura da Web aplicativos foi alterado e matured (com a popularidade de aplicativos de Internet rich [RIAs], por exemplo), houve um maior reconhecimento do valor de exposição de dados não processados, menos qualquer interface ou formatação, para qualquer serviço ou aplicativo que desejar consumi-lo. Serviços de dados são simples serviços de centrado em dados com uma interface RESTful, que faz exatamente isso — expor dados puro para consumo por aplicativos. Esses serviços expõem dados usando uma interface uniforme para ser consumida pelos clientes da Web em uma intranet corporativa ou na Internet. Serviços de dados podem ser criados e hospedados em suas instalações usando a biblioteca de servidor de serviços de dados ADO.NET para expor dados com segurança como um serviço, ou podem ser disponibilizados por vários serviços hospedados, como Windows Azure tabela. Windows Azure é a base da plataforma de nuvem a Microsoft. Como "sistema operacional de nuvem" ele fornece os blocos construção essenciais, você precisa criar serviços escalonáveis e altamente disponíveis. Uma parte importante da Azure, tabela de Azure do Windows, permite aos usuários manter dados na nuvem e expor os dados que ele armazena como um serviço de dados.

Independentemente de onde o serviço de dados está hospedado, a estrutura de serviços de dados ADO.NET fornece que um conjunto de bibliotecas de cliente criado para uma variedade de plataformas de desenvolvimento da Microsoft (.NET, Silverlight, ASP.NET AJAX e assim por diante) que permitem que você facilmente consumir esses serviços em seus aplicativos.

fig01.gif

Figura 1 modelo de entidades de dados exposto pelo serviço de dados de Micro-Blogging

O aplicativo

No decorrer deste artigo, irá ser criando um aplicativo de Micro-Blogging simples usando ASP.NET MVC (Model View controlador) (versão RC) e explicará em detalhes alguns dos cenários típicos que surgem ao criar esses aplicativos baseada em serviços. Eu assumirá uma compreensão anterior de MVC e, portanto, não discutir as especificidades desse padrão. Se você precisar obter mais informações sobre MVC do ASP.NET, consulte oSite ASP.NET MCV. Para fins de comparação, eu veremos duas versões do mesmo aplicativo básico — um consumo de um serviço de dados em locais e um consumindo um serviço de dados de tabela Azure. O código para as duas versões é incluído no download de código que acompanha.

O aplicativo de Micro-Blogging permite que os usuários postar mensagens em canais específicos, criar novos canais e exibir mensagens nos canais de interesse para eles. O modelo que foi exposto pelo serviço de dados para esse aplicativo consiste em três tipos de entidades: mensagens, canais e usuários, com um mapeamento um-para-um amplamente para o banco de dados. Vale a pena observar neste ponto, que com uma fonte de dados em locais, esse modelo contém uma noção de primeira classe de relações entre entidades. As mensagens são lançadas em um canal específico por um usuário individual (veja a Figura 1 ).

Consumir um serviço de dados em locais com a biblioteca de cliente de serviços dados ADO.NET

Vamos começar criando um novo MVC aplicativo ASP.NET usando o modelo Visual Studio instalado com o ASP.NET MVC.

Há duas maneiras principais que você pode ir sobre como definir as classes para representar o modelo no cliente. Você pode simplesmente definir o modelo definindo as classes POCO (antiga simples CLR Objects) que serão usadas no cliente para representar as entidades expostas pelo serviço, farei quando que desenvolver este aplicativo em Windows Azure tabela, ou você pode usar o Assistente para Adicionar referência de serviço no Visual Studio para gerar as classes necessárias. Como quando você usar Adicionar referência de serviço para um serviço Windows Communication Foundation (WCF), basta clicar com o botão direito do mouse no projeto e escolha Add Service Reference. Na caixa de diálogo Add Service Reference, digite o URI para o ponto de entrada do serviço como o endereço e clique em OK. Isso irá gerar classes associadas, baseadas na definição de serviço de dados e adicioná-los ao projeto.

Como visto na Figura 2 , o Assistente para Adicionar referência de serviço gerou uma classe para cada um dos meus entidades: canal, mensagem e usuário, bem como uma classe que representa o serviço como um todo — microblogEntities. O microblogEntities classe herda DataServiceContext e serão usado como o ponto de partida para acessar o serviço de dados.

fig02.gif

A Figura 2 classes representação Micro-Blogging modelo

Consultando dados

Com o aplicativo configurou para acessar o serviço de dados, É possível iniciar o restante do meu aplicativo de desenvolvimento. Na página inicial, o aplicativo fornece uma listagem dos canais disponíveis e permitir que o usuário exibir mensagens de hoje, selecionando um canal. O usuário também poderá filtrar em que canais baseado no autor. Para criar a home page, precisará criar um ActionResult no controlador de página inicial que será mapeado para o modo de exibição índice (o controlador de início e o modo de exibição de índice são criados por padrão no modelo MVC). Na página inicial, será preciso recuperar uma lista de todos os canais disponíveis do serviço de dados, também consulta o serviço para mensagens de hoje, a filtragem com base na entrada do usuário (veja a Figura 3 ).

fig03.gif

A Figura 3 home page do site

A biblioteca de cliente ADO.NET Data Service permite facilmente dados da consulta com o uso de consulta integrada de idioma (LINQ), como você pode ver na A Figura 4 .

A ação de índice do controlador de home page é chamada pelo aplicativo MVC quando a home page é acessada pelo navegador e retorna os dados que serão usados para processar o modo de exibição Index.aspx. Na Figura 4 , dentro da ação de índice, eu instanciar uma nova instância do microblogEntities DataServiceContext, assim:

microblogEntities svc = new microblogEntities(new Uri("http://localhost:50396/MicroData.svc"));

A Figura 4 acesso a dados como objetos .NET usando LINQ

public ActionResult Index(string channel, string author)
    {
        microblogEntities svc = new microblogEntities(new 
        Uri("http://localhost:50396/MicroData.svc"));
        ViewData["channels"] = svc.Channels;

        int y = DateTime.Now.Year;
        int mm = DateTime.Now.Month;
        int d = DateTime.Now.Day;

        var q = from m in svc.Messages.Expand("Author").Expand("Channel")
                where m.Channel.ChannelName == channel && (m.DatePosted.Year == y && 
                m.DatePosted.Month == mm && m.DatePosted.Day == d)
                select m;

        if (!string.IsNullOrEmpty(author))
        {
            q = from m in q
                where m.Author.UserName == author
                select m;
        }

        ViewData["msg"] = q;

        return View();
    }

Esse é o objeto que VOU usar sempre desejar atingido o serviço. A primeira consulta que será executada contra o serviço de dados acessa todos os canais disponíveis. O segundo, uma consulta LINQ, recupera todas as mensagens no canal que foi solicitada quando o usuário atinge a página e filtros pelo autor se foi fornecido um nome. Observe que no código de exemplo fornecido, as mensagens são exibidas, inserindo o nome do canal e, se desejar, o nome do autor para a caixa de texto e, em seguida, clicando em Exibir. Também vale a pena observar que as consultas exigem um ChannelName; e uma pesquisa não pode ser executada pelo nome do autor sozinho. EU colocar ambas as consultas mencionadas anteriormente em ViewData para ser executado como a página é processada e, em seguida, retornar.

Agora, no modo de exibição para a home page, Index.aspx, serão realmente enumerar as consultas, efetivamente executar a consulta contra o armazenamento neste ponto e, em seguida, irá mostrar os resultados para a página (consulte A Figura 5 ).

A Figura 5 Exibir de home page (em locais Service)

<h2>Today's Messages</h2>
    <form action="./">
        Channel:<span style="color: #FF0000">*</span> <input type="text" 
            name="channel" 
            />          
            Author: <input type="text" name="author" /><br />
        <input type="submit" value="Search" />
    </form> 
    <ul>
    <!-- Execute query placed in ViewData["msg"] - enumerates over 
        results and prints resulting message data to the screen -->
    <% foreach (var m in (Ienumerable
        <MicroBloggingOnPremise.Models.Message>)
    ViewData["msg"])
       { %>
    <li><%=m.Author.UserName%>@<%=m.DatePosted %>: <%=m.Text%> 
        [<%=m.Channel.ChannelName %>]</li>
    <%} %>
    </ul>



    <h2>Channels</h2>
    <ul>
    <!-- Execute query placed in ViewData["channels"] - enumerates over 
         results and prints resulting channel data to the screen -->
        <% foreach (var channel in 
        (IEnumerable<MicroBloggingOnPremise.Models.Channel>)
            ViewData["channels"])
           { %>

          <li><%=channel.ChannelName %> (<%=channel.DateCreated %>)</li>

        <% } %>
    </ul>

Criar, atualização e excluir

Para criar uma nova instância de entidade no serviço de dados usando a biblioteca de cliente ADO.NET Data Service, criar uma nova instância do objeto .NET que representa o conjunto de entidade e chame o método AddTo… para o conjunto de entidade na instância do DataServiceContext que eu estou usando, passando o novo objeto e a entidade definir que eu estou adicionando-a.

Por exemplo, vamos consulte ação de controlador de home page, PostMessage em A Figura 6 , que é chamado quando tento enviar uma mensagem, clique no botão Enviar.

A Figura 6 (em locais) criar uma nova mensagem e envio para armazenamento de dados

[AcceptVerbs("POST")]
        public ActionResult PostMessage(string channel, string author, 
            string msg)
        {
            microblogEntities svc = new microblogEntities(new 
            Uri("http://localhost:50396/MicroData.svc"));

            Channel chan = (from c in svc.Channels
                    where c.ChannelName == channel
                    select c).FirstOrDefault();


            if (chan == null) throw new ArgumentException("Invalid 
                channel");

            User u = (from auth in svc.Users
                     where auth.UserName == author
                     select auth).FirstOrDefault();

            if (u == null) //throw new ArgumentException("Invalid 
                Author");
            {
                //To simplify this example we will create a new user, 
                //if the user was null when we queried. 
                //It is possible that another client creates 
                //the same UserName 
                //before we call SaveChanges() 
                //and we end up with 2 Users with the same name
                var user = new User();
                user.UserName = author;
                user.DateCreated = DateTime.UtcNow;
                svc.AddToUsers(user);
                u = user;

            }


            var m = new Message();

            m.DatePosted = DateTime.UtcNow;
            m.Text = msg;
            svc.AddToMessages(m);
            svc.SetLink(m, "Channel", chan);
            svc.SetLink(m, "Author", u);

            try
            {
                svc.SaveChanges();
            }
            catch (Exception e)
            {
                throw (e);
            }
            return this.RedirectToAction("Index");
        }

Observe que o método está decorado com o atributo AcceptVerbs("POST"), como estamos usando ele para uma postagem de formulário. Novamente iniciado pela instanciação de um novo DataServiceContext como a entrada aponte para o meu serviço e, em seguida, consulta para o canal especificado verificar se ele existe. Se o canal não existir, eu gero uma exceção; caso contrário, criar uma nova mensagem passando os dados inseridos pelo usuário. Depois da mensagem tiver sido criada, precisará informar o contexto que eu tenho um novo objeto a ser adicionado por chamada svc.AddToMessages(m); passando o novo objeto de mensagem, m. Também defini links que representa as relações anexadas a esta nova mensagem, esse svc.SetLink(m, "Channel", chan) caso associando a mensagem de canal e svc.SetLink(m, "Author", u) especificados; associando a mensagem com o autor especificado. Finalmente, eu desejo enviar as alterações ao serviço e para o banco de dados chamando svc.SaveChanges();.

Se eu estava modificando uma instância existente em vez de criar um novo, eu poderia primeiro consulta para o objeto que eu quero atualizar, faça as alterações desejadas, e em vez de AddToMessages, seria chamo o UpdateObject método para indicar ao contexto que ele precisa enviar uma atualização para o objeto na próxima vez que eu chamo SaveChanges(). Da mesma forma, se eu foram excluindo uma instância, depois que eu tinha o objeto, eu poderia chame o método Delete para indicar ao contexto que que deseja excluir esse objeto.

Neste exemplo e até o momento neste artigo, você já viu uma única operação no mapa de cliente para uma única solicitação HTTP enviado para o serviço. Em muitos cenários, também é útil para o cliente para ser capaz de lote de um grupo de operações e envie-os para o serviço em uma única solicitação HTTP. Isso reduz o número de viagens de ida e volta para o serviço e permite que um escopo lógico de atomicidade para conjuntos de operações. A biblioteca de cliente ADO.NET Data Service oferece suporte para envio de um grupo de Insert, Update, e / ou solicitam operações de excluir a um serviço em um único HTTP por meio de uma chamada para o método SaveChanges(), passando SaveChangesOptions.Batch como o único parâmetro. Esse valor do parâmetro instrui o cliente ao lote todas as alterações pendentes em uma única solicitação HTTP enviada para o serviço. Enviando alterações como um lote, impedirá que todas as alterações serão concluído com êxito ou nenhuma das alterações serão aplicadas.

Consumir um serviço de dados de tabela Azure

Quando você estiver desenvolvendo um aplicativo .NET usando Windows Azure tabela, os dados são acessados usando as bibliotecas de cliente de serviços de dados ADO.NET. Nesta seção, irá percorrer o desenvolvimento do mesmo aplicativo simples usado acima, mas desta vez eu será acessar e manipular dados armazenados na tabela Azure. Parta para o restante deste artigo, eu princípio de que uma conta de Windows Azure armazenamento já foi configurada e é disponível para seu uso. Para obter mais informações sobre a Introdução ao Windows Azure tabela, consulte o Azure Services plataforma Developer Center.

O modelo de dados de tabela Azure

Antes de começar em um aplicativo, existem algumas coisas que você deve saber sobre o modelo de dados de tabela Azure para obter melhor desempenho (em inglês). Um aplicativo pode optar por criar várias tabelas em uma conta de armazenamento em que cada tabela contém um conjunto de entidades (linhas) e cada entidade contém um conjunto de propriedades (colunas). Cada entidade é capaz de ter até 255 propriedades, armazenadas como < Nome, TypedValue > pares e é identificada usando duas propriedades de chaves que juntos se tornam a identificação exclusiva. Esta primeira propriedade de chave é o PartitionKey (cadeia de caracteres de tipo), a habilitação de particionamento para escalabilidade e a outra é RowKey (também o tipo de seqüência), identificando exclusivamente a entidade na partição. Além das duas propriedades chaves, não há nenhum esquema fixa para as propriedades restantes, que significa que o aplicativo é responsável por impor qualquer esquema que deve ser mantida.

Uma das diferenças importantes ao desenvolver em Windows Azure tabela comparado ao banco de dados local Armazenamento cerca de particionamento. Com Azure tabela, o aplicativo controla a granularidade de partições e particionamento se torna muito importante para o desempenho e escalabilidade do aplicativo. Isso significa que a opção da propriedade PartitionKey é muito importante e afeta o desempenho porque a tabela clusters entidades (localidade de entidade) com o mesmo valor de chave de partição. Para escolher os melhores possíveis PartitionKey, você deve escolher a chave, que ele seja comum a maioria (ou todos) das consultas usadas no aplicativo. Um impacto no desempenho e escalabilidade podem também ser da mesma forma pelo número de partições usadas pelo aplicativo (número de valores diferentes no PartitionKey); permite ter mais partições que o servidor saldo melhor a carga entre nós.

Biblioteca de cliente de serviços de dados do ADO.NET

Agora será criar o mesmo aplicativo Micro-Blogging usando ASP.NET modo de exibição controlador (MVC) e desta vez eu explicará em detalhes algumas das perguntas que normalmente surgem ao criar aplicativos em dados armazenados no Windows Azure tabela.

Semelhante ao meu banco de dados em locais, isso exigirá três entidades no meu modelo, serão convertidos em três tabelas: uma tabela de mensagens, uma tabela de canais e uma tabela de usuários, todos definidos no minha conta de armazenamento.

Em todo o aplicativo será utilizam o StorageClient exemplo fornecido no SDK do Windows Azure. O exemplo de StorageClient implementa uma biblioteca que você pode usar para acessar o serviço de armazenamento do Windows Azure blob, serviço de fila e o serviço de armazenamento de tabela. VOU usar a biblioteca para ajudar a me acessar o serviço de armazenamento de tabela. O SDK do Windows Azure pode ser baixado do Azure Services plataforma Developer Center citadas anteriormente.

Para começar, VOU criar um novo MVC aplicativo ASP.NET usando o modelo Visual Studio instalado com o ASP.NET MVC e adicionar o projeto StorageClient no SDK do Windows Azure à solução.

Definir o modelo no cliente

A primeira etapa na criação do aplicativo é definir as classes que serão usadas no cliente para representar as entidades expostas pelo serviço. Como Azure tabela não tem um esquema de fixo, não CONSIGO usar o Assistente para Adicionar referência de serviço como fiz com o serviço em locais. No entanto, como mencionei anteriormente, É possível criar Meus próprio classes POCO. Essas classes efetivamente serão usadas para definir o esquema para o aplicativo, como tabela Azure não aplica qualquer esquema no lado do servidor. Irá definir uma classe de mensagem, uma classe de canal e uma classe de usuário para alinhar o EntityTypes expostos pelo serviço. Para começar, adicionar um novo arquivo de código, MicroData.cs, para a pasta Modelos onde que irá definir minhas classes. Essas classes serão definidas no namespace MicroBloggingAzure.Models.

Se você fizer uma olhada a classe de mensagens mostrada na Figura 7 , você pode ver que eu tenha definido tanto um PartitionKey e um RowKey, conforme exigido pela tabela Azure. Este é um desvio de que você viu no serviço em locais porque elas são específicas para Windows Azure tabela. Vale a pena observar que as práticas recomendadas para a determinação de chave não são recomendadas em armazenamento relacional e nuvem, e em meus aplicativos de exemplo usei a determinação de chave mais apropriada para cada fonte de dados em vez de tentar alinhar os dois de forma alguma. O PartitionKey e o RowKey são simplesmente definido como seqüência de caracteres de tipo e identificados usando convenções de nomes (que está, chamando-los PartitionKey e RowKey). No caso deste aplicativo, o PartitionKey é formado por nome do canal no qual a mensagem será lançada, concatenado com um "@" e a data a mensagem lançada no formato" DD-mm-dd ". O RowKey é uma representação de seqüência de caracteres da data em que a mensagem foi lançada. Este PartitionKey foi escolhido, que o aplicativo possa recuperar com eficiência as mensagens que foram lançadas recentemente a um canal específico. Para começar com, optou por mostrar somente as postagens de hoje quando um canal é acessado; no entanto, se meu aplicativo torna-se bastante popular e recebe milhares de postagens um dia, essa chave pode ser facilmente modificada para partição mais granular — por exemplo, adicionando um componente de tempo (horas talvez). Da mesma forma, se meu aplicativo não estiver tão ocupado como previsto, eu poderia modificar o PartitionKey a partição pelo mês em vez de por dia. Em seguida, identificou as duas propriedades da chave como um DataServiceKey de identificação exclusivo, que é feito adicionando o atributo de DataServiceKey à classe. A classe de mensagens também define um número de outras propriedades que contém informações sobre a mensagem, uma parte as chaves necessárias. Todas as propriedades associadas com a entidade de mensagem serão armazenadas na tabela Azure. As classes de usuário e de canal são criadas seguindo os mesmos princípios que a classe de mensagem.

A Figura 7 mensagem entidade definição

[DataServiceKey("PartitionKey", "RowKey")]
    public class Message
    {
        // ParitionKey is channel name [+ day]
        public string PartitionKey { get; set; }
        // Date/Time when the message was created
        public string RowKey { get; set; }

        public string Text { get; set; }
        public string Author { get; set; }
        public string Channel { get; set; }
        public DateTime DatePosted { get; set; }
        public int Rating { get; set; }

        public Message()
        {
        }

        public Message(string channel, string author, string text)
        {
            this.Text = text;
            this.Author = author;
            this.Channel = channel;
            this.DatePosted = DateTime.UtcNow;

            this.PartitionKey = MakeKey(this.Channel, this.DatePosted);
            this.RowKey = System.Xml.XmlConvert.ToString(
               this.DatePosted);
        }
        public static string MakeKey(string channel, DateTime dt)
        {
            return channel + "@" + dt.ToString("yyyy-MM-dd");
        }
    }

Criar uma tabela

Depois que minhas classes de entidade tem sido definidos, pode começar realmente desenvolvendo o aplicativo. Mas primeiro, preciso adicionar minhas informações de acesso de Azure tabela conta a Web.config, como mostrado aqui:

<appSettings>
  <add key="TableStorageEndpoint"        value="http://table.core.windows.net/"/>
  <add key="AccountName" value="<MyAccountName>"/>
  <add key="AccountSharedKey" value="<MyAccountSharedKey-Provided when       
 you register for Azure Tables>"/>
</appSettings>

Embora isso não seja a única maneira de passar informações da conta ao desenvolver em relação à tabela Azure, isso permitirá que eu usar o SDK Azure para pegar minhas configurações de conta e lidar com conexões com a fonte de dados automaticamente.

Com freqüência em aplicativos escritos em Windows Azure tabela, a criação de tabelas necessários para o aplicativo é feita através de programação dentro do aplicativo. Isso é um pouco diferente de como um normalmente faria coisas com um local em armazenamento de dados, onde as tabelas são criadas separadamente no banco de dados e o aplicativo simplesmente interage com eles.

Uma maneira de criar as tabelas necessárias através de programação deve ser simplesmente criar uma nova entidade na tabela mestra chamado tabelas. Cada tabela que você cria na sua conta de armazenamento deve ser representada como uma entidade na tabela mestra, que é predefinida ao registrar sua conta. Para este aplicativo, no entanto, usará o StorageClient, que fornece funcionalidade para verificar, na inicialização do aplicativo, que as tabelas necessárias existem na conta de armazenamento, e se elas não existirem, criará-los.

Criando as tabelas por meio de programação dentro do aplicativo, simplificam o processo pelo qual eu pode refletir atualizações para o modelo no armazenamento de dados. Por exemplo, se para baixo de trânsito aumentar a capacidade para um usuário se inscrever em um canal e adicionar uma entidade de inscrição para o modelo, a tabela associada será automaticamente adicionada ao armazenamento de dados a próxima vez que o aplicativo for iniciado. Essa opção também garante que se o aplicativo é distribuído para uso com contas Azure tabelas diferentes, tudo o que o usuário precisa fazer é insira sua informações de acesso de conta e as tabelas corretamente configuradas e pronto para uso quando o aplicativo é executado.

Se você tiver dados existentes na tabela Azure, ou se você não tem controle sobre as tabelas em Azure, você pode ignore a etapa de criação de tabelas completamente e simplesmente programar as tabelas existentes.

Para verificar e criar as tabelas no meu aplicativo, será use o método de TableStorage.CreateTablesFromModel() que faz parte da biblioteca StorageClient, como mostrado aqui:

protected void Application_Start()
{
       RegisterRoutes(RouteTable.Routes); //MVC Routing Rules

       TableStorage.CreateTablesFromModel (typeof(Models.MicroData));
}  

Consultando dados

Com meu aplicativo configurado para acessar minha conta em Azure tabelas, o restante funciona exatamente como se eu estava acessando um service em locais. Assim como com meu serviço em locais, como ESTOU usando a biblioteca de cliente do ADO.NET Data Service, estou capaz de facilmente trabalhar com meus dados como objetos .NET e consultá-lo usando o LINQ (consulte a Figura 8 ).

A Figura 8 acesso a dados como objetos .NET usando LINQ novamente

public ActionResult Index(string channel, string author)
        {
            var svc = new Models.MicroData();
            ViewData["channels"] = svc.Channels;

            var q = from m in svc.Messages
                    where m.PartitionKey == Models.Message.
                       MakeKey(channel, DateTime.UtcNow)
                    select m;
            if (!string.IsNullOrEmpty(author))
            {
                q = from m in q
                    where m.Author == author
                    select m;
            }

            ViewData["msg"] = q;

            return View();
        }

Na Figura 8 , você vê a ação de índice do controlador de home page. Dentro dessa ação, eu instanciar uma nova instância do meu DataServiceContext (MicroData herda TableStorageDataServiceContext), o objeto usar para acessar o serviço e gravar as consultas a ser executada contra o serviço de dados. Eu, em seguida, recuperar uma lista de todos os canais disponíveis do serviço de dados e escrever a consulta LINQ para recuperar todas as mensagens atuais, filtragem com base na entrada do usuário (canal e possivelmente autor se fornecida). EU colocar as duas consultas em ViewData para ser executado como a página é processada e, em seguida, retornar. Observe que o padrão aqui é o mesmo quando eu acessado a fonte de dados em locais; instanciar uma nova instância de DataServiceContext e consultar usando simples consultas do LINQ em meu modelo.

No modo de exibição para minha home page (Index.aspx em A Figura 9 ), Eu enumerar Meus consultas, executar as consultas contra o armazenamento e imprimir os resultados para a página.

A Figura 9 Modo de home page

<h2>Today's Messages</h2>
    <form action="./">
        Channel:<span style="color: #FF0000">*</span> <input type="text" 
        name="channel" /><br />
        Author: <input type="text" name="author" /><br />
        <input type="submit" value="View" />
    </form> 
    <ul>
    <!-- Execute query placed in ViewData["msg"] - enumerates over 
         results and prints resulting message data to the screen -->
    <% foreach (var m in (IEnumerable<MicroBloggingAzure.Models.Message>)
       ViewData["msg"])
       { %>
    <li><%=m.Author%>@<%=m.DatePosted %>: <%=m.Text%> [<%=m.Channel %>]
    </li>
    <%} %>
    </ul>


   <h2>Channels</h2>

    <ul>
    <!-- Execute query placed in ViewData["channels"] - enumerates over 
    Results and prints resulting channel data to the screen -->
        <% foreach (var channel in 
        (IEnumerable<MicroBloggingAzure.Models.Channel>)
        ViewData["channels"])
        { %>

          <li><%=channel.PartitionKey %> (<%=channel.DateCreated %>)</li>

        <% } %>
       </ul>

Criar, atualização e excluir

Criar uma nova entidade no serviço de tabela usando a biblioteca de cliente do ADO.NET Data Service, como se eu estava trabalhando em um armazenamento em locais, é feito por criar uma nova instância do objeto .NET que representa o conjunto de entidade e chamando AddObject().

Vamos examinar a ação PostMessage do meu controlador de home page, em A Figura 10 .

A Figura 10 criar nova mensagem e envio para armazenamento de dados

[AcceptVerbs("POST")]
        public ActionResult PostMessage(string channel, string author, string msg)
        {
            var svc = new Models.MicroData();

            var q = from c in svc.Channels
                    where c.PartitionKey == channel
                    select c;

            if (q.FirstOrDefault() == null) throw new
            ArgumentException("Invalid channel");

            User u = (from auth in svc.Users
                     where auth.UserName == author
                     select auth).FirstOrDefault();

            if (u == null)
            //throw new ArgumentException("Invalid Author");
            {
                var user = new User();
                user.UserName = author;
                user.DateCreated = DateTime.UtcNow;
                user.PartitionKey = user.UserName;
                user.RowKey = string.Empty;
                svc.AddObject("Users", user);
                u = user;
            }

            var m = new Models.Message(channel, author, msg);
            svc.AddObject("Messages", m);

            svc.SaveChanges();

            return this.RedirectToAction("Index");
        }

Assim como fiz para consultar o serviço de dados, eu instanciar um novo DataServiceContext como o ponto de entrada e a consulta para o canal especificado para verificar se ele existir, emitir uma exceção se ele não for encontrado. Eu crio uma nova mensagem, passando a entrada do usuário. Após a mensagem ter sido criada, saber o contexto que eu tenha um novo objeto a ser adicionado por chamada svc.AddObject ("mensagens", m); passagem no nome do EntitySet que ESTOU acrescentando a, "mensagens" e novo objeto de mensagem, m. Finalmente, eu desejo enviar as alterações para o serviço de tabela, chamando svc.SaveChanges();.

Há algumas diferenças que você poderá notar aqui. A primeira é devido à falta de um esquema fixo na tabela Azure. Essa falta de esquema significa que eu não têm dados com rigidez de tipos e deve chamar o AddObject() não tipado na instância DataServiceContext, passando o novo objeto e a entidade definir que eu estou adicionando, em vez de armazenam os métodos de AddTo…() digitados que usei em meu local. Vale a pena observar aqui se o método AddObject() mais genérico ainda está disponível no cenário em locais; no entanto, no meu exemplo usar os métodos com rigidez de tipos para aproveitar o tempo de compilação verificação e assim por diante.

Segundo a diferença, também um pouco atribuída a falta de esquema fixa, é a falta de um conceito de relação de primeira classe. Você primeiro observar isso nas diferenças entre como eu estruturar os dados na tabela Azure em comparação com minha fonte de dados em locais. A ação PostMessage você observará que eu não estou definindo links no meu novo objeto; em vez disso, qualquer informação de relacionamento é armazenada diretamente como propriedades em Meus entidades.

Se eu estava modificando uma instância existente em vez de criar um novo, deve primeiro consultar para o objeto deseja atualizar, faça as alterações desejadas e, finalmente, em vez de AddObject, eu poderia chame o método UpdateObject para indicar ao contexto que ele precisa enviar uma atualização para o objeto na próxima vez que eu chamo SaveChanges(), mesma maneira que faria com um serviço de dados em locais. Da mesma forma, excluir uma instância chamando o método Delete para indicar ao contexto que que deseja excluir esse objeto, é também o mesmo se eu estou acessar um serviço de tabela Azure ou meu próprio serviço em locais.

Soma para cima

Examinar esses dois exemplos juntos, você pode ver como simples a movimentação entre o desenvolvimento em um serviço em premissa e um serviço de tabela Azure é feito pelo uso do mesmo simples ADO.NET biblioteca de dados dos serviços de cliente. A curva de aprendizado envolvida é bastante simples se você também for responsável pelo gerenciamento de cada fonte de dados e consiste principalmente em uma mudança no pensamento entre o modelo de armazenamento relacional e o modelo de tabela Azure mais não estruturado, bem como um conhecimento do modelo Azure tabela PartitionKey e RowKey. Se você é voltadas principalmente o desenvolvimento de aplicativo contra esses serviços, as habilidades que você cria desenvolvimento contra um serviço são transferíveis para o desenvolvimento com qualquer outro serviço de dados.

Elisa Flasko é gerente de programa na equipe do dados programação na Microsoft, incluindo as tecnologias, tecnologias XML e tecnologias de conectividade do SQL Server do ADO.NET. Ela pode ser contatada pelo blogs.msdn.com/elisaj.