Fazendo Joins com CAML Query
Olá!
Cenário:
O SharePoint 2010 introduziu uma novidade na maneira de realizar queries usando as já conhecidas CAML Queries. Agora podemos utilizar Joins (e campos projetados) em nossas CAML queries, economizando esforço e até ganhando performance nas queries para alcançar alguns objetivos que antes, no SharePoint 2007, não havia o que fazer.
No MSDN encontramos bastante documentação a respeito, mas ainda um tanto confuso. Pelo menos eu achei.
http://msdn.microsoft.com/en-us/library/ee539975.aspx – List Joins and Projections
SOLUÇÃO:
Primeiramente vamos preparar o ambiente que vamos fazer nossos testes.
· Crie duas listas em seu SharePoint, uma lista chamada Eventos (do tipo Personalizada ou Custom List) e outra lista chamada Contatos (do tipo Contatos ou Contacts)
Nas lista de Eventos, crie uma coluna do tipo Loopkup (consulta) para a lista de Contatos, chamada Responsavel (sem acento).
Vá na lista de Contatos e adicione alguns registros:
Volte a lista de Eventos e também adicione alguns registros, associando contatos aos Eventos:
Pronto, agora temos o ambiente preparado. Iremos listar todos os eventos e mostrar o título do Evento, Nome e SobreNome (informação que está na outra lista) com apenas uma única query.
static void Main(string[] args)
{
ShowJoin();
}
private static void ShowJoin()
{
using (SPSite site = new SPSite("http://notebook02/sites/treinamento"))
{
using (SPWeb web = site.OpenWeb())
{
SPQuery query = new SPQuery();
query.Query = @"<OrderBy>
<FieldRef Name='Title' />
</OrderBy>";
query.Joins = "<Join Type='INNER' ListAlias='Contatos'>" +
"<Eq>" +
"<FieldRef Name='Responsavel' RefType='Id'/>" +
"<FieldRef List='Contatos' Name='ID'/>" +
"</Eq>" +
"</Join>";
query.ProjectedFields =
"<Field Name='Nome' Type='Lookup' " +
"List='Contatos' ShowField='FirstName'/>" +
"<Field Name='SobreNome' Type='Lookup' " +
"List='Contatos' ShowField='Title'/>";
query.ViewFields = "<FieldRef Name='Title'/>" +
"<FieldRef Name='Nome'/>" +
"<FieldRef Name='SobreNome'/>";
SPList listaEventos = web.Lists["Eventos"];
SPListItemCollection items = listaEventos.GetItems(query);
if (items.Count > 0)
{
foreach (SPListItem item in items)
{
SPFieldLookupValue dseLastName =
new SPFieldLookupValue(item["SobreNome"].ToString());
SPFieldLookupValue dseFirstName =
new SPFieldLookupValue(item["Nome"].ToString());
Console.WriteLine("Nome do Evento: {0}, SobreNome do Reponsável: {1}, Nome do Responsável: {2}",
item.Title,
dseLastName.LookupValue,
dseFirstName.LookupValue);
}
Console.ReadLine();
}
}
}
}
Explicando:
SPQuery query = new SPQuery();
query.Query = @"<OrderBy>
<FieldRef Name='Title' />
</OrderBy>";
Até aqui normal, a mesma query que sempre utilizamos. Nesse caso, apenas ordenando pelo título do evento.
query.Joins = "<Join Type='INNER' ListAlias='Contatos'>" +
"<Eq>" +
"<FieldRef Name='Responsavel' RefType='Id'/>" +
"<FieldRef List='Contatos' Name='ID'/>" +
"</Eq>" +
"</Join>";
Aqui montamos a condição do Join que iremos fazer com a lista Contatos (lembrando que nossa query roda na lista Eventos).
query.ProjectedFields =
"<Field Name='Nome' Type='Lookup' " +
"List='Contatos' ShowField='FirstName'/>" +
"<Field Name='SobreNome' Type='Lookup' " +
"List='Contatos' ShowField='Title'/>";
Aqui projetamos os campos da lista Contatos na “lista” Eventos. Na verdade, os campos são projetados apenas no SPListItemCollection retornado na query. Damos um alias (Name) para o campo e vinculamos ao nome interno (ShowField) do campo na lista Contatos. Então, nossos itens retornados terão as colunas projetadas Nome e SobreNome, da lista Contatos, juntamente com todas as colunas da lista de Eventos.
query.ViewFields = "<FieldRef Name='Title'/>" +
"<FieldRef Name='Nome'/>" +
"<FieldRef Name='SobreNome'/>";
Aqui explicitamos apenas os campos que queremos retornados na query. Ou seja, a query trará APENAS os campos relacionados abaixo. Bom procedimento quando queremos performance, afinal, por que trazer todos os campos se apenas vamos usar alguns?
Percebam que usei os alias criados anteriormente e não mais o nomes reais da lista Contatos (que seriam Title, para LastName, e FirstName).
Ao mandar rodar, temos:
Campos de outra lista projetados no resultado da query. E o melhor, podemos fazer query na outra lista já nessa mesma query! Exemplo:
query.Query = @"<Where>
<Eq>
<FieldRef Name='Nome' />
<Value Type='Text'>Thiago</Value>
</Eq>
</Where>
<OrderBy>
<FieldRef Name='Title' />
</OrderBy>";
O campo Nome, que usei na query, não “existe” em nenhuma das listas. É o alias, ou campo projetado, criado aqui:
query.ProjectedFields =
"<Field Name='Nome' Type='Lookup' " +
"List='Contatos' ShowField='FirstName'/>" +
"<Field Name='SobreNome' Type='Lookup' " +
"List='Contatos' ShowField='Title'/>";
Vamos testar! De acordo com a Query, é para trazer ordenado pelo título do evento, apenas os eventos que o Nome do responsável seja igual a Thiago.
É isso aí, até mais! ![]()
Abraço!
Como Inserir e Configurar uma WebPart de Gráfico de Barras
Olá!
Fiz esse vídeo há algum tempo, mas havia esquecido de subir e compartilhar. Bem simples, mas que pode ser útil para quem for fazer isso pela primeira vez.
No vídeo mostro como inserir e configurar uma Web Part de Gráfico de Barras, conectada a uma lista com informações do SharePoint. Infelizmente, no processo de upload para o Youtube, a qualidade do audio caiu um pouco mas acho que dá pra seguir bem.
Abraço!
The content type text/html; charset=utf-8 of the response message does not match the content type of the binding
Olá! ![]()
Cenário:
Desenvolver para SharePoint 2010 usando Visual Studio 2010 é infinitamente melhor e mais produtivo do que desenvolver para SharePoint 2007 usando Visual Studio 2008.
Mas, como a vida dá voltas, me deparo com o cenário vivido por muito tempo. E tempo esse sensacional entendendo a estrutura do SharePoint.
Eis que ao montar um novo ambiente de desenvolvimento para SharePoint 2007, usando o Visual Studio eXtensions for Windows SharePoint Services (VSeWSS) 3.0, me deparo com um erro ao tentar montar um pacote .wsp “Package” ou tentar montar fazer um deploy no servidor.
ERRO:
Error: System.ServiceModel.ProtocolException System.ServiceModel.ProtocolException: The content type text/html; charset=utf-8 of the response message does not match the content type of the binding (text/xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 1024 bytes of the response were: ‘<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>IIS 7.0 Detailed Error – 500.0 – Internal Server Error</title> <style type="text/css"> <!– body{margin:0;font-size:.7em;font-family:Verdana,Arial,Helvetica,sans-serif;background:#CBE1EF;} code{margin:0;color:#006600;font-size:1.1em;font-weight:bold;} .config_source code{font-size:.8em;color:#000000;} pre{margin:0;font-size:1.4em;word-wrap:break-word;} ul,ol{margin:10px 0 10px 40px;} ul.first,ol.first{margin-top:5px;} fieldset{padding:0 15px 10px 15px;} .summary-container fieldset{padding-bottom:5px;margin-top:4px;} legend.no-expand-all{padding:2px 15px 4px 10px;margin:0 0 0 -12px;} legend{color:#333333;padding:4px 15px 4px 10px;margin:4px 0 8px -12px;_margin-top:0px; border-top:1px solid #EDEDED;border-left:1px solid #EDEDED;border-right:1px solid #969696; border-bottom:1px solid #969696;background:#E7ECF0;font-weight:bold;f’. —> System.Net.WebException: The remote server returned an error: (500) Internal Server Error. at System.Net.HttpWebRequest.GetResponse().
SOLUÇÃO:
Para resolver o problema precisamos nos certificar que o Windows Communication Foundation HTTP Activation esteja ativado no servidor.
Para isso, vamos aos passos:
Abra o Server Manager > Features > Add Features:
No seletor de features marque a opção HTTP Activation, em .Net Framework Features > WCF Activation:
Clique em Next e Install para instalar a feature. Feito isso, o deploy irá funcionar.
—— Generate solution file and setup batch file ——
Creating solution …
Operation completed successfully.
Creating setup batch file …
Operation completed successfully.
—— Packaged successfully to C:\Projects\Sebrae\DoneIT.Sebrae.PortfolioWeb\bin\Debug\DoneIT.Sebrae.PortfolioWeb.wsp ——
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
========== Deploy: 1 succeeded, 0 failed, 0 skipped ==========
Abraço!
The requested OLE DB provider Microsoft.Jet.OLEDB.4.0 is not registered — perhaps no 64-bit provider is available
Olá! ![]()
Cenário:
Automatizando alguns processos e/ou coletando informações de diversas fontes de dados para centralizar relatórios em um único ponto (SharePoint!) precisamos criar mecanismos de extração e carga das informações (ETL).
Na experiência deste post, precisei extrair as informações de banco de dados Access (.mdb) e jogar a informação em tabela no SQL.
Ao utilizar o provider nativo de acesso a fonte de dados Access e mandar rodar a extração me deparo com um erro.
ERRO:
The requested OLE DB provider Microsoft.Jet.OLEDB.4.0 is not registered — perhaps no 64-bit provider is available.
E de fato, como podemos ler, não existe a versão deste provider para plataforma 64 bits: http://support.microsoft.com/kb/957570.
SOLUÇÃO:
Para resolver o problema forcei o pacote do SQL Server Integration Services (SSIS) rodar como 32 bits, tanto no Business Intelligence Management Studio (BIMS) quanto no Timer no SQL Server Agent.
No BIMS, nas propriedades de configuração do projeto:
No Job do SQL Server Agent:
Abraço!
2011 in review
The WordPress.com stats helper monkeys prepared a 2011 annual report for this blog.
Here’s an excerpt:
The concert hall at the Sydney Opera House holds 2,700 people. This blog was viewed about 16,000 times in 2011. If it were a concert at Sydney Opera House, it would take about 6 sold-out performances for that many people to see it.
Forçar Download arquivos PDF em Bibliotecas de Documentos em uma WebPart Customizada
Olá! ![]()
Cenário:
Muitas vezes desenvolvendo soluções para SharePoint esbarramos com alguns “pequenos” comportamentos que o usuário solicita uma mudança.
A bola da vez foi que o comportamento padrão de arquivos PDF é abrir no browser (falando de IE, por exemplo). Então, temos uma aplicação customizada que lista os documentos de uma biblioteca e imprime o link do documento na tela para download.
Nos arquivos PDFs o browser entende e abre o documento no browser. Precisamos que seja forçado o download.
SOLUÇÃO:
Existem diversas formas de fazer isso, customizando ainda a aplicação. Mas(!) estamos trabalhando o SharePoint e com isso, temos toda a infraestrutura que já está nele!
Ora pois, o SharePoint já faz download de arquivos nativamente:
· No Ribbon
· No menu de contexto do item:
Então, por que não utilizar o que SharePoint já usa? (Sempre persiga isso! Se o SharePoint já faz, tente usar!)
Peace of cake! Com um pouco de debug feelings… descobrimos que o SharePoint simplesmente chama um página passando um parâmetro.
Ou seja, faça um simples <a href=”/_layouts/download.aspx?SourceUrl=http://sharepoint/Documents /Arquivo.pdf”></a> e o SharePoint forçará o download.
Abraço!
