SlideShare ist ein Scribd-Unternehmen logo
1 von 48
Resumão da Sessão Técnica


Effective Geodatabase Programming
        By Craig Gillgrass, Erik Hoel




                                                   Bruno Caimar
                                        Imagem Soluções Verticais
                                                     Abril / 2012
Atenção:

 Essa apresentação foi criada com base em minhas
anotações da apresentação desse ano e nos slides da
apresentação do DevSummit de 2011 que podem ser
                   obtidos em:

                  http://bit.ly/JoaoHv
Essa não é uma sessão introdutória

Nós assumimos que:

* Possuem conhecimento pratico de
Geodatabase e alguma experiencia em
desenvolvimento utilizando a API

* Códigos de exemplos em Java e C#

* Muito conteúdo técnico, pouco tempo

* Best practices / Questões comuns
Resumo

• Instâncias únicas de objetos

• Cursores

• Schema Cache

• Geodatabase Schema Simplificado

• Erros mais comuns (Do not do list)
Instâncias únicas de objetos
• Objetos de geodatabase que possuem SEMPRE no
   máximo uma instância
   - São similares a objetos COM Singletons exceto que eles
   não são 'cocreateables'
   - Exemplos:
    - Datasets (tables, feature classes, feature datasets)
    - Workspaces e Versions

• Independente da API que retornou a referência, ela é
   SEMPRE a mesma referência

* Alterações em um objeto AFETAM todos outros que
   contem referência para o mesmo
Instâncias únicas de objetos
Instâncias únicas de objetos
                   Caso especial

    RowsFeatures são instâncias únicas apenas em sessões
                          de edição
Cursores

    Três tipos de classes de cursores
    - Search (Cursor de busca em geral)
    - Update (Cursor de atualização posicional)
    - Insert (Cursor de inclusão em bloco)

    Um cursor 'QueryDef'
    - Consulta definida (e.g., IQueryDef.Evaluate)

 Qual a diferença?
 * Linhas criadas por cursores de classes são vinculadas a
classe que criou o cursor
 * Linhas criadas por cursores 'QueryDef' não são vinculadas
a uma classe
Cursores - Exemplo
Cursores - Consulta

    Todas as classes baseadas na API de consulta
- API's comuns que criam cursores de consulta (search)
- ITable.Search / GetRow / GetRows, ISelectionSet.Search


 Em uma sessão de edição, a consulta pode ser
atendida por uma cache (spatial cache, object pool)

• Utilizando em uma sessão de edição irá liberar (flush)
as linhas cacheadas (apenas da classe)
 - Pode resultar em uma gravação no banco de dados

 Linhas consultadas podem ser modificadas
- Store/Delete suportados
Cursores - Atualização
• Cursores de atualização posicional
  - NextRow->UpdateRow …NextRow->UpdateRow
  - Atualiza a linha na posição corrente do cursor

• APIs comuns para criação de cursores de atualização
  - ITable.Update, ISelectionSet2.Update

• A consulta NUNCA é atendida por um cache

• Utilizando em uma sessão de edição irá liberar (flush) as
   linhas cacheadas da classe em questão

• Linhas consultadas podem ser modificadas utilizando-se
    ICursor.UpdateRow ou ICursor.DeleteRow
  - Store e Delete NÃO devem ser utilizados
Cursores - Atualização
• Se a classe suportar os eventos de 'Store' então...
  - Um cursor interno é criado e UpdateRow e DeleteRow se
    tornam equivalentes a Row.Store e Row.Delete

• Como saber?
  - Feature types não simples (!esriFTSimple)
  - Classes participantes em uma Geometric Network,
    Relationships que requerem mensagens
  - Features customizadas (ObjectClassExtension overrides)

• Comportamento do método UpdateRow
  - Erro se chamado em uma linha (row) que não foi obtida de
    um cursor de atualização
  - Erro se chamado em uma linha (row) for da posição atual
    do cursor
Cursores - Atualização
                   Melhores Práticas
• Não utilize um cursor de atualização entre operações de
    edição (uma exceção será lançada a partir do 10.0)
  - isso é MUITO importante quando se está editando dados
    versionados

• Cursores de atualização 'apontam' para uma estado
    especifico do banco de dados
  - Esse estado pode alterado durante sessões de edição
  - Alterações podem ser perdidas

• Best Practice: SEMPRE mantenha seu cursor de
    atualização dentro do escopo de uma operação de edição
  - se você iniciar uma nova operação de edição você DEVE
    iniciar um novo cursor de atualização
Cursores - Inclusão


• Recomendado para inclusões em massa (bulk insert)

• API para criar um cursor de inclusão
  - ITable.Insert

• Melhor performance quando utilizado com buffer e flush
  apropriados

• Se a classe suportar eventos de 'Store' então InsertRow
   internamente se tornará um CreateRow e Store
Cursores – Inclusão - Buffering
• Passar 'true' no argumento “useBuffering” do método
   ITable.Insert

• Periodicamente chamar o Flush
  - 1000 linhas por vez é um bom número para começar
  - Quanto maior o intervalo de flush menor o trafego de rede
    (mas maior o trabalho de re-inclusão, se necessário)

• Certifique-se que a classe não possua cache espacial –
   processamento extra é requerido para manter o cache
   sincronizado

• IMPORTANTE: as chamadas tanto para InsertRow e Flush
   devem possuir tratamento de erro adequado porque
   ambos podem resultar em escrita no banco de dados
Buffering com Enterprise GeoDB's
Buffering com Enterprise GeoDB's
Cursores – QueryDef

• Executam query's definidas pelo usuário (não ligadas a
   classes)

• Cursores QueryDef nunca utilizam qualquer tipo de cache
   (classe ou workspace)

• Chamada de IQueryDef.Evaluate dentro de um sessão de
   edição irá provocar um 'flush' de todas as linha em cache

• Linhas retornadas por esse tipo de cursor não suportam
   modificação (Store e Delete)
O que são Recycling Cursors?

• Um “recycling cursor” é um cursor que não cria um novo
   objeto de linha no cliente para cada linha retornada pelo db

• Estruturas e objetos internos são reutilizados
- Memória
- instâncias (exemplo: Geometry)

• Métodos da API que suportam a criação de “recycling
  cursors” possuem sempre um argumento booleano:
  - recycling = true cria um “recycling cursor”
O que são Non-Recycling Cursors?

• Um cursor que cria um novo objeto no cliente para cada
   registro retornado pelo banco de dados

• Estruturas e objetos internos são criados para cada registro
  - Memory
  - instâncias (e.g., Geometry)

• Métodos da API que suportam a criação de “recycling
  cursors” possuem sempre um argumento booleano:
  - recycling = true cria um “recycling cursor”
Recycling Cursors
•Interfaces com métodos que podem criar “recycling cursors”

•ITable / IFeatureClass
   -GetRows / GetFeatures
   -Search
   -Update

•ISelectionSet / ISelectionSet2
   -Search
   -Update

•ITableWrite
   -UpdateRows
Recycling cursor - Exemplo
• Chamadas a NextRow resultam sempre na mesma
   instância
Recycling Cursor - Exemplo
Recycling Cursors–Quando utilizar?
• Quando você não precisa de uma referência persistente
   para um registro

• NÃO passe referências adiante!
  - Isole o uso das referências em métodos locais onde o
    “recycling cursor” foi criado para minimizar o potencial de
    bugs (em outras palavras: não passe referências para
    outros métodos pois eles podem decidir mantê-las)

• NUNCA faça uma edição diretamente em um registro
   reciclado (recycled row)

• Uso apropriado em sessões de edição pode reduzir
   DRAMATICAMENTE o consumo de recursos
Recycling Cursor
Exemplo consumo de recursos
Non-Recycling Cursors–Quando
              utilizar?
• Quando você precisa de uma referência persistente para
   um registro ou para algum valor do registro

• Quando você precisa editar o registro ou passar uma
   referência do mesmo adiante

• Utilizado normalmente para fazer um 'cache' de um
   conjunto de registros (long lived references)

• Algumas API's requerem um conjunto de registros – nesse
   caso, esse conjunto deve ser obtido como non-recycled
   rows
FAQ - Cursores


Quando eu devo liberar a referência de um cursor?

Não mantenha uma referência a um cursor se não for
  necessário.
Libere ASAP.
FAQ - Cursores
Se eu preciso de um cursor em uma sessão de edição
  onde eu devo criá-lo?

Dentro do seu bloco de edição
(startEditOperation/stopEditOperation)

O importante é NUNCA cruzar fronteiras de operações de
  edição.
FAQ - Cursores


Devo utilizar um cursor de consulta (Search) para
  atualizar registros?

Sim. Na verdade, cursores de consulta são a forma
  recomendada de atualizar registros em sessões de edição.
FAQ - Cursores
Que tipo de cursor eu devo utilizar para alterações?




•ArcMap – possibilidade do cache satisfazer a consulta e nenhuma consulta ao
   BD ser necessária

• Engine Simple Data
- Dentro ES – tira vantagem das atualizações em lote em operações de edição
- Outside ES – performance, possibilidade de tratar erros por registro

• Engine Complex Data – Independente. O sistema irá emular uma consulta
   internamente
Schema Cache

* Um snapshot do schema do geodatabase
   - Utilizado pelo ArcGIS (abertura de Map Documents,
   Reconcile)
   - Requer um um modelo de dados estático
    - Mudanças no schema não serão refletidas no cache

* Pode melhorar a performance na abertura de datasets
   reduzindo as consultas ao banco de dados

• Schema Cache API
   - IWorkspaceFactorySchemaCache
Schema Simplificado – ArcGIS 10


• No ArcGIS 10 o schema do geodatabase foi reconstruído

  - Estrutura mais simples (4 tabelas GDB_* ao invés de
  35+)
  - Capacidades de busca otimizadas
  - Schema aberto (sem serialização binária)
  - Bem documentado
  - XML
Schema Simplificado – ArcGIS 10
• Acesso mais fácil as informações

• Mais escalável para um
numero grande de datasets

• Melhor performance nas
consultas ao schema

• Melhor 'fundação' para suportar
mais tipos de dataset no futuro

• Suporte a “File Geodatabase API”

• Suporte a “forward compatibility”
(a partir do ArcGIS 10 SP2)
Erros mais comuns
• Uso incorreto de “recycling cursors”
• Chamadas a FindField em loops
• Utilização de cursor entre operações de edição
• DDL em sessões de edição
• Chamadas a “Store” dentro de eventos disparados por
“store”
• Utilização de GetFeature ao invés de GetFeatures
• Reuso descuidado de variáveis
• Alteração de objetos de schema que não são persistidos
• Inclusões e notificações de “relationship class”
Uso incorreto de “recycling cursors”
Chamadas a FindField em loops
• Utilizar FindField ao invés de posições “hard-coded” é UMA
         boa pratica mas o uso excessivo pode impactar
                           performance
Utilização de cursor entre
           operações de edição
•   Isso está documentado como “NÃO FAÇA ISSO!”

•   Bloqueado a partir do 10.0
DDL em sessões de edição
• Métodos que podem disparar comandos DDL, como
  IFeatureWorkspace.CreateTable ou Iclass.AddField devem
  ser evitados dentro de sessões de edição
  - Comandos DDL irão efetuar “commit” em qualquer
  transação corrente, tornando impossível efetuar “rollback”
  em qualquer edição não desejada se algum erro ocorrer.


- Exemplo: uma aplicação de edição customizada que
   adiciona um valor a um domínio baseado em um valor
   informado pelo usuário pode falhar inesperadamente
   quando da tentativa de “commit” das alterações.
Chamadas a “Store” em eventos
       disparados por “store”
• Chamar “Store” no mesmo objeto dispara o modelo de
   eventos, levando a um comportamento inesperado.

  - Em alguns casos isso pode resultar em recursão infinita
  fazendo a aplicação travar. Em outros casos erros podem
  ser retornados com mensagens que podem ser difíceis de
  interpretar
Utilização de GetFeature ao invés
             de GetFeatures

  Performance: Toda vez que mais de uma feature for
retornada utilizando um objectID conhecido, SEMPRE utilize
o método GetFeatures

  Evite fazer chamadas individuais (GetFeature) se isso for
possível
Reuso descuidado de variáveis
Alteração de objetos de schema
       que não são persistidos
• Em modificações de objetos – e.g., datasets, domains,
   fields, etc., você deve estar atento ao fato dessas classes
   serem divididas em duas categorias com os seguintes
   comportamentos:
   - Aquelas que serão automaticamente persistidas (“tables”)
   - Aquelas que podem não ser (fields, domains, indexes)
• Um exemplo clássico são os métodos IClass.AddField() e
   IFieldsEdit.AddField()
   - quando o 1o é chamado a API adiciona o campo a tabela
   no banco de dados
   - quando o 2o é chamado o campo é adicionado somente
   na memória. A alteração não é efetuada no banco de
   dados
Inclusões e notificações de
            “relationship class”
• Notificações (também conhecida como mensagens) garante
   o comportamento apropriado em relacionamentos
   compostos, feature-linked annotation e custom class
   extensions
   - Esse comportamento tem um custo
   - Inclusões e alterações em datasets que disparam
   notificações são notadamente mais lentos que as mesmas
   operações em datasets sem notificação

• Essa perda de performance pode ser minimizada se
   cerificando que todas as classes que serão notificadas
   estejam abertas antes de qualquer inclusãoalteração
Inclusões e notificações de
    “relationship class”
Erros mais comuns
• Uso incorreto de “recycling cursors”
• Chamadas a FindField em loops
• Utilização de cursor entre operações de edição
• DDL em sessões de edição
• Chamadas a “Store” dentro de eventos disparados por
“store”
• Utilização de GetFeature ao invés de GetFeatures
• Reuso descuidado de variáveis
• Alteração de objetos de schema que não são persistidos
• Inclusões e notificações de “relationship class”
GeoDB Developer Resources


• ESRI Blogs (blogs.esri.com)
   - Inside the Geodatabase

• Geodatabase
   “How To” Articles
    - Developers Guide to the Geodatabase
            - Many more articles in Geodatabase SDK
More GeoDB Developer Resources
Effective Geodatabase Programming – ESRI DevSummit 2012
http://video.esri.com/series/87/2012-esri-developer-summit-technical-workshops


Effective Geodatabase Programming – ESRI DevSummit 2011
http://proceedings.esri.com/library/userconf/devsummit11/tech/tech_39.html
http://proceedings.esri.com/library/userconf/devsummit11/videos/video64.html
    http://proceedings.esri.com/library/userconf/devsummit11/papers/tech/effective_geodatabas


Common Geodatabase API Programming Mistakes (9.3)
http://resources.esri.com/help/9.3/ArcGISEngine/dotnet/09bd8059-f031-4b88-bac8-3b4b73dccb05.htm


Geodatabase API best practices (10)
http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#//000100000047000000


XML Schema of Geodatabase “White Paper”
http://downloads.esri.com/support/whitepapers/ao_/XML_Schema_of_Geodatabase.pdf
Obrigado!

     Bruno Caimar
Imagem Soluções Verticais
  bcaimar@img.com.br

       Abril/2012

Weitere ähnliche Inhalte

Ähnlich wie Effective Geodatabase Programming

C# 6.0 - Interopmix 2015
C# 6.0 - Interopmix 2015C# 6.0 - Interopmix 2015
C# 6.0 - Interopmix 2015Renato Groff
 
Três anos de Scala no NewsMonitor
Três anos de Scala no NewsMonitorTrês anos de Scala no NewsMonitor
Três anos de Scala no NewsMonitorFelipe Hummel
 
Introdução a JPA (2010)
Introdução a JPA (2010)Introdução a JPA (2010)
Introdução a JPA (2010)Helder da Rocha
 
ASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre TarifaASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre Tarifaguestea329c
 
Monitorando APIs REST com o Application Insights
Monitorando APIs REST com o Application InsightsMonitorando APIs REST com o Application Insights
Monitorando APIs REST com o Application InsightsRenato Groff
 
Construindo APIs REST escaláveis na nuvem com Docker e Kubernetes - DEVPIRA F...
Construindo APIs REST escaláveis na nuvem com Docker e Kubernetes - DEVPIRA F...Construindo APIs REST escaláveis na nuvem com Docker e Kubernetes - DEVPIRA F...
Construindo APIs REST escaláveis na nuvem com Docker e Kubernetes - DEVPIRA F...Renato Groff
 
Processos iniciais do mapeamento OR
Processos iniciais do mapeamento ORProcessos iniciais do mapeamento OR
Processos iniciais do mapeamento ORNécio de Lima Veras
 
Pgday Campinas 2015 - Uma visão do PPAS 9.4 e PEM 5.0
Pgday Campinas 2015 - Uma visão do PPAS 9.4 e PEM 5.0Pgday Campinas 2015 - Uma visão do PPAS 9.4 e PEM 5.0
Pgday Campinas 2015 - Uma visão do PPAS 9.4 e PEM 5.0Marcos William Valentini
 
Pgday Campinas 2015 - Uma visão do PPAS 9.4 e PEM 5.0
Pgday Campinas 2015 - Uma visão do PPAS 9.4 e PEM 5.0Pgday Campinas 2015 - Uma visão do PPAS 9.4 e PEM 5.0
Pgday Campinas 2015 - Uma visão do PPAS 9.4 e PEM 5.0Marcos William Valentini
 
364722271-Modulo-III-Linguagem-SQL-Versao-Final.pdf
364722271-Modulo-III-Linguagem-SQL-Versao-Final.pdf364722271-Modulo-III-Linguagem-SQL-Versao-Final.pdf
364722271-Modulo-III-Linguagem-SQL-Versao-Final.pdfQuitriaSilva550
 
Projeto Octopus - Database Sharding para ActiveRecord
Projeto Octopus - Database Sharding para ActiveRecordProjeto Octopus - Database Sharding para ActiveRecord
Projeto Octopus - Database Sharding para ActiveRecordtchandy
 
Otimizacao de websites em PHP
Otimizacao de websites em PHPOtimizacao de websites em PHP
Otimizacao de websites em PHPFelipe Ribeiro
 
Cakephp - framework de desenvolvimento de aplicações Web em PHP
Cakephp - framework de desenvolvimento de aplicações Web em PHPCakephp - framework de desenvolvimento de aplicações Web em PHP
Cakephp - framework de desenvolvimento de aplicações Web em PHPArlindo Santos
 
C# 6.0 - DotNetBaixada - Novembro/2015
C# 6.0 - DotNetBaixada - Novembro/2015C# 6.0 - DotNetBaixada - Novembro/2015
C# 6.0 - DotNetBaixada - Novembro/2015Renato Groff
 

Ähnlich wie Effective Geodatabase Programming (20)

Aula 06 - TEP - Introdução SQLite
Aula 06 - TEP - Introdução SQLiteAula 06 - TEP - Introdução SQLite
Aula 06 - TEP - Introdução SQLite
 
C# 6.0 - Interopmix 2015
C# 6.0 - Interopmix 2015C# 6.0 - Interopmix 2015
C# 6.0 - Interopmix 2015
 
Três anos de Scala no NewsMonitor
Três anos de Scala no NewsMonitorTrês anos de Scala no NewsMonitor
Três anos de Scala no NewsMonitor
 
Introdução a JPA (2010)
Introdução a JPA (2010)Introdução a JPA (2010)
Introdução a JPA (2010)
 
ASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre TarifaASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre Tarifa
 
ASP.NET MVC
ASP.NET MVCASP.NET MVC
ASP.NET MVC
 
Otimizando a performance com in-memory no SQL 2016
Otimizando a performance com in-memory no SQL 2016Otimizando a performance com in-memory no SQL 2016
Otimizando a performance com in-memory no SQL 2016
 
08 modificadores static
08   modificadores static08   modificadores static
08 modificadores static
 
Monitorando APIs REST com o Application Insights
Monitorando APIs REST com o Application InsightsMonitorando APIs REST com o Application Insights
Monitorando APIs REST com o Application Insights
 
Mapeamento de herança OR
Mapeamento de herança ORMapeamento de herança OR
Mapeamento de herança OR
 
Construindo APIs REST escaláveis na nuvem com Docker e Kubernetes - DEVPIRA F...
Construindo APIs REST escaláveis na nuvem com Docker e Kubernetes - DEVPIRA F...Construindo APIs REST escaláveis na nuvem com Docker e Kubernetes - DEVPIRA F...
Construindo APIs REST escaláveis na nuvem com Docker e Kubernetes - DEVPIRA F...
 
Processos iniciais do mapeamento OR
Processos iniciais do mapeamento ORProcessos iniciais do mapeamento OR
Processos iniciais do mapeamento OR
 
Pgday Campinas 2015 - Uma visão do PPAS 9.4 e PEM 5.0
Pgday Campinas 2015 - Uma visão do PPAS 9.4 e PEM 5.0Pgday Campinas 2015 - Uma visão do PPAS 9.4 e PEM 5.0
Pgday Campinas 2015 - Uma visão do PPAS 9.4 e PEM 5.0
 
Pgday Campinas 2015 - Uma visão do PPAS 9.4 e PEM 5.0
Pgday Campinas 2015 - Uma visão do PPAS 9.4 e PEM 5.0Pgday Campinas 2015 - Uma visão do PPAS 9.4 e PEM 5.0
Pgday Campinas 2015 - Uma visão do PPAS 9.4 e PEM 5.0
 
364722271-Modulo-III-Linguagem-SQL-Versao-Final.pdf
364722271-Modulo-III-Linguagem-SQL-Versao-Final.pdf364722271-Modulo-III-Linguagem-SQL-Versao-Final.pdf
364722271-Modulo-III-Linguagem-SQL-Versao-Final.pdf
 
Projeto Octopus - Database Sharding para ActiveRecord
Projeto Octopus - Database Sharding para ActiveRecordProjeto Octopus - Database Sharding para ActiveRecord
Projeto Octopus - Database Sharding para ActiveRecord
 
Otimizacao de websites em PHP
Otimizacao de websites em PHPOtimizacao de websites em PHP
Otimizacao de websites em PHP
 
Otimizando a performance com in memory no sql 2016
Otimizando a performance com in memory no sql 2016Otimizando a performance com in memory no sql 2016
Otimizando a performance com in memory no sql 2016
 
Cakephp - framework de desenvolvimento de aplicações Web em PHP
Cakephp - framework de desenvolvimento de aplicações Web em PHPCakephp - framework de desenvolvimento de aplicações Web em PHP
Cakephp - framework de desenvolvimento de aplicações Web em PHP
 
C# 6.0 - DotNetBaixada - Novembro/2015
C# 6.0 - DotNetBaixada - Novembro/2015C# 6.0 - DotNetBaixada - Novembro/2015
C# 6.0 - DotNetBaixada - Novembro/2015
 

Effective Geodatabase Programming

  • 1. Resumão da Sessão Técnica Effective Geodatabase Programming By Craig Gillgrass, Erik Hoel Bruno Caimar Imagem Soluções Verticais Abril / 2012
  • 2. Atenção: Essa apresentação foi criada com base em minhas anotações da apresentação desse ano e nos slides da apresentação do DevSummit de 2011 que podem ser obtidos em: http://bit.ly/JoaoHv
  • 3. Essa não é uma sessão introdutória Nós assumimos que: * Possuem conhecimento pratico de Geodatabase e alguma experiencia em desenvolvimento utilizando a API * Códigos de exemplos em Java e C# * Muito conteúdo técnico, pouco tempo * Best practices / Questões comuns
  • 4. Resumo • Instâncias únicas de objetos • Cursores • Schema Cache • Geodatabase Schema Simplificado • Erros mais comuns (Do not do list)
  • 5. Instâncias únicas de objetos • Objetos de geodatabase que possuem SEMPRE no máximo uma instância - São similares a objetos COM Singletons exceto que eles não são 'cocreateables' - Exemplos: - Datasets (tables, feature classes, feature datasets) - Workspaces e Versions • Independente da API que retornou a referência, ela é SEMPRE a mesma referência * Alterações em um objeto AFETAM todos outros que contem referência para o mesmo
  • 7. Instâncias únicas de objetos Caso especial  RowsFeatures são instâncias únicas apenas em sessões de edição
  • 8. Cursores  Três tipos de classes de cursores - Search (Cursor de busca em geral) - Update (Cursor de atualização posicional) - Insert (Cursor de inclusão em bloco)  Um cursor 'QueryDef' - Consulta definida (e.g., IQueryDef.Evaluate)  Qual a diferença? * Linhas criadas por cursores de classes são vinculadas a classe que criou o cursor * Linhas criadas por cursores 'QueryDef' não são vinculadas a uma classe
  • 10. Cursores - Consulta  Todas as classes baseadas na API de consulta - API's comuns que criam cursores de consulta (search) - ITable.Search / GetRow / GetRows, ISelectionSet.Search  Em uma sessão de edição, a consulta pode ser atendida por uma cache (spatial cache, object pool) • Utilizando em uma sessão de edição irá liberar (flush) as linhas cacheadas (apenas da classe) - Pode resultar em uma gravação no banco de dados  Linhas consultadas podem ser modificadas - Store/Delete suportados
  • 11. Cursores - Atualização • Cursores de atualização posicional - NextRow->UpdateRow …NextRow->UpdateRow - Atualiza a linha na posição corrente do cursor • APIs comuns para criação de cursores de atualização - ITable.Update, ISelectionSet2.Update • A consulta NUNCA é atendida por um cache • Utilizando em uma sessão de edição irá liberar (flush) as linhas cacheadas da classe em questão • Linhas consultadas podem ser modificadas utilizando-se ICursor.UpdateRow ou ICursor.DeleteRow - Store e Delete NÃO devem ser utilizados
  • 12. Cursores - Atualização • Se a classe suportar os eventos de 'Store' então... - Um cursor interno é criado e UpdateRow e DeleteRow se tornam equivalentes a Row.Store e Row.Delete • Como saber? - Feature types não simples (!esriFTSimple) - Classes participantes em uma Geometric Network, Relationships que requerem mensagens - Features customizadas (ObjectClassExtension overrides) • Comportamento do método UpdateRow - Erro se chamado em uma linha (row) que não foi obtida de um cursor de atualização - Erro se chamado em uma linha (row) for da posição atual do cursor
  • 13. Cursores - Atualização Melhores Práticas • Não utilize um cursor de atualização entre operações de edição (uma exceção será lançada a partir do 10.0) - isso é MUITO importante quando se está editando dados versionados • Cursores de atualização 'apontam' para uma estado especifico do banco de dados - Esse estado pode alterado durante sessões de edição - Alterações podem ser perdidas • Best Practice: SEMPRE mantenha seu cursor de atualização dentro do escopo de uma operação de edição - se você iniciar uma nova operação de edição você DEVE iniciar um novo cursor de atualização
  • 14. Cursores - Inclusão • Recomendado para inclusões em massa (bulk insert) • API para criar um cursor de inclusão - ITable.Insert • Melhor performance quando utilizado com buffer e flush apropriados • Se a classe suportar eventos de 'Store' então InsertRow internamente se tornará um CreateRow e Store
  • 15. Cursores – Inclusão - Buffering • Passar 'true' no argumento “useBuffering” do método ITable.Insert • Periodicamente chamar o Flush - 1000 linhas por vez é um bom número para começar - Quanto maior o intervalo de flush menor o trafego de rede (mas maior o trabalho de re-inclusão, se necessário) • Certifique-se que a classe não possua cache espacial – processamento extra é requerido para manter o cache sincronizado • IMPORTANTE: as chamadas tanto para InsertRow e Flush devem possuir tratamento de erro adequado porque ambos podem resultar em escrita no banco de dados
  • 18. Cursores – QueryDef • Executam query's definidas pelo usuário (não ligadas a classes) • Cursores QueryDef nunca utilizam qualquer tipo de cache (classe ou workspace) • Chamada de IQueryDef.Evaluate dentro de um sessão de edição irá provocar um 'flush' de todas as linha em cache • Linhas retornadas por esse tipo de cursor não suportam modificação (Store e Delete)
  • 19. O que são Recycling Cursors? • Um “recycling cursor” é um cursor que não cria um novo objeto de linha no cliente para cada linha retornada pelo db • Estruturas e objetos internos são reutilizados - Memória - instâncias (exemplo: Geometry) • Métodos da API que suportam a criação de “recycling cursors” possuem sempre um argumento booleano: - recycling = true cria um “recycling cursor”
  • 20. O que são Non-Recycling Cursors? • Um cursor que cria um novo objeto no cliente para cada registro retornado pelo banco de dados • Estruturas e objetos internos são criados para cada registro - Memory - instâncias (e.g., Geometry) • Métodos da API que suportam a criação de “recycling cursors” possuem sempre um argumento booleano: - recycling = true cria um “recycling cursor”
  • 21. Recycling Cursors •Interfaces com métodos que podem criar “recycling cursors” •ITable / IFeatureClass -GetRows / GetFeatures -Search -Update •ISelectionSet / ISelectionSet2 -Search -Update •ITableWrite -UpdateRows
  • 22. Recycling cursor - Exemplo • Chamadas a NextRow resultam sempre na mesma instância
  • 24. Recycling Cursors–Quando utilizar? • Quando você não precisa de uma referência persistente para um registro • NÃO passe referências adiante! - Isole o uso das referências em métodos locais onde o “recycling cursor” foi criado para minimizar o potencial de bugs (em outras palavras: não passe referências para outros métodos pois eles podem decidir mantê-las) • NUNCA faça uma edição diretamente em um registro reciclado (recycled row) • Uso apropriado em sessões de edição pode reduzir DRAMATICAMENTE o consumo de recursos
  • 26. Non-Recycling Cursors–Quando utilizar? • Quando você precisa de uma referência persistente para um registro ou para algum valor do registro • Quando você precisa editar o registro ou passar uma referência do mesmo adiante • Utilizado normalmente para fazer um 'cache' de um conjunto de registros (long lived references) • Algumas API's requerem um conjunto de registros – nesse caso, esse conjunto deve ser obtido como non-recycled rows
  • 27. FAQ - Cursores Quando eu devo liberar a referência de um cursor? Não mantenha uma referência a um cursor se não for necessário. Libere ASAP.
  • 28. FAQ - Cursores Se eu preciso de um cursor em uma sessão de edição onde eu devo criá-lo? Dentro do seu bloco de edição (startEditOperation/stopEditOperation) O importante é NUNCA cruzar fronteiras de operações de edição.
  • 29. FAQ - Cursores Devo utilizar um cursor de consulta (Search) para atualizar registros? Sim. Na verdade, cursores de consulta são a forma recomendada de atualizar registros em sessões de edição.
  • 30. FAQ - Cursores Que tipo de cursor eu devo utilizar para alterações? •ArcMap – possibilidade do cache satisfazer a consulta e nenhuma consulta ao BD ser necessária • Engine Simple Data - Dentro ES – tira vantagem das atualizações em lote em operações de edição - Outside ES – performance, possibilidade de tratar erros por registro • Engine Complex Data – Independente. O sistema irá emular uma consulta internamente
  • 31. Schema Cache * Um snapshot do schema do geodatabase - Utilizado pelo ArcGIS (abertura de Map Documents, Reconcile) - Requer um um modelo de dados estático - Mudanças no schema não serão refletidas no cache * Pode melhorar a performance na abertura de datasets reduzindo as consultas ao banco de dados • Schema Cache API - IWorkspaceFactorySchemaCache
  • 32. Schema Simplificado – ArcGIS 10 • No ArcGIS 10 o schema do geodatabase foi reconstruído - Estrutura mais simples (4 tabelas GDB_* ao invés de 35+) - Capacidades de busca otimizadas - Schema aberto (sem serialização binária) - Bem documentado - XML
  • 33. Schema Simplificado – ArcGIS 10 • Acesso mais fácil as informações • Mais escalável para um numero grande de datasets • Melhor performance nas consultas ao schema • Melhor 'fundação' para suportar mais tipos de dataset no futuro • Suporte a “File Geodatabase API” • Suporte a “forward compatibility” (a partir do ArcGIS 10 SP2)
  • 34. Erros mais comuns • Uso incorreto de “recycling cursors” • Chamadas a FindField em loops • Utilização de cursor entre operações de edição • DDL em sessões de edição • Chamadas a “Store” dentro de eventos disparados por “store” • Utilização de GetFeature ao invés de GetFeatures • Reuso descuidado de variáveis • Alteração de objetos de schema que não são persistidos • Inclusões e notificações de “relationship class”
  • 35. Uso incorreto de “recycling cursors”
  • 36. Chamadas a FindField em loops • Utilizar FindField ao invés de posições “hard-coded” é UMA boa pratica mas o uso excessivo pode impactar performance
  • 37. Utilização de cursor entre operações de edição • Isso está documentado como “NÃO FAÇA ISSO!” • Bloqueado a partir do 10.0
  • 38. DDL em sessões de edição • Métodos que podem disparar comandos DDL, como IFeatureWorkspace.CreateTable ou Iclass.AddField devem ser evitados dentro de sessões de edição - Comandos DDL irão efetuar “commit” em qualquer transação corrente, tornando impossível efetuar “rollback” em qualquer edição não desejada se algum erro ocorrer. - Exemplo: uma aplicação de edição customizada que adiciona um valor a um domínio baseado em um valor informado pelo usuário pode falhar inesperadamente quando da tentativa de “commit” das alterações.
  • 39. Chamadas a “Store” em eventos disparados por “store” • Chamar “Store” no mesmo objeto dispara o modelo de eventos, levando a um comportamento inesperado. - Em alguns casos isso pode resultar em recursão infinita fazendo a aplicação travar. Em outros casos erros podem ser retornados com mensagens que podem ser difíceis de interpretar
  • 40. Utilização de GetFeature ao invés de GetFeatures  Performance: Toda vez que mais de uma feature for retornada utilizando um objectID conhecido, SEMPRE utilize o método GetFeatures  Evite fazer chamadas individuais (GetFeature) se isso for possível
  • 41. Reuso descuidado de variáveis
  • 42. Alteração de objetos de schema que não são persistidos • Em modificações de objetos – e.g., datasets, domains, fields, etc., você deve estar atento ao fato dessas classes serem divididas em duas categorias com os seguintes comportamentos: - Aquelas que serão automaticamente persistidas (“tables”) - Aquelas que podem não ser (fields, domains, indexes) • Um exemplo clássico são os métodos IClass.AddField() e IFieldsEdit.AddField() - quando o 1o é chamado a API adiciona o campo a tabela no banco de dados - quando o 2o é chamado o campo é adicionado somente na memória. A alteração não é efetuada no banco de dados
  • 43. Inclusões e notificações de “relationship class” • Notificações (também conhecida como mensagens) garante o comportamento apropriado em relacionamentos compostos, feature-linked annotation e custom class extensions - Esse comportamento tem um custo - Inclusões e alterações em datasets que disparam notificações são notadamente mais lentos que as mesmas operações em datasets sem notificação • Essa perda de performance pode ser minimizada se cerificando que todas as classes que serão notificadas estejam abertas antes de qualquer inclusãoalteração
  • 44. Inclusões e notificações de “relationship class”
  • 45. Erros mais comuns • Uso incorreto de “recycling cursors” • Chamadas a FindField em loops • Utilização de cursor entre operações de edição • DDL em sessões de edição • Chamadas a “Store” dentro de eventos disparados por “store” • Utilização de GetFeature ao invés de GetFeatures • Reuso descuidado de variáveis • Alteração de objetos de schema que não são persistidos • Inclusões e notificações de “relationship class”
  • 46. GeoDB Developer Resources • ESRI Blogs (blogs.esri.com) - Inside the Geodatabase • Geodatabase “How To” Articles - Developers Guide to the Geodatabase - Many more articles in Geodatabase SDK
  • 47. More GeoDB Developer Resources Effective Geodatabase Programming – ESRI DevSummit 2012 http://video.esri.com/series/87/2012-esri-developer-summit-technical-workshops Effective Geodatabase Programming – ESRI DevSummit 2011 http://proceedings.esri.com/library/userconf/devsummit11/tech/tech_39.html http://proceedings.esri.com/library/userconf/devsummit11/videos/video64.html http://proceedings.esri.com/library/userconf/devsummit11/papers/tech/effective_geodatabas Common Geodatabase API Programming Mistakes (9.3) http://resources.esri.com/help/9.3/ArcGISEngine/dotnet/09bd8059-f031-4b88-bac8-3b4b73dccb05.htm Geodatabase API best practices (10) http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#//000100000047000000 XML Schema of Geodatabase “White Paper” http://downloads.esri.com/support/whitepapers/ao_/XML_Schema_of_Geodatabase.pdf
  • 48. Obrigado! Bruno Caimar Imagem Soluções Verticais bcaimar@img.com.br Abril/2012

Hinweis der Redaktion

  1. Slides para referencia futura Bastante coisa sobre cursores
  2. Explicar o código. Diferentes formas de obter os objetos porem todas retornam a mesma instância
  3. Cursores são um tipo de objeto muito comum para desenvolvedores GIS 1o Tipo - Class cursors 2o Tipo - QueryDef Cursors
  4. * Importante: Dependendo da query que está sendo executada isso pode gerar um write (commit). Be AWARE of that. Tenho isso em mente! * Algumas vezes isso pode dar erro e o erro que pode ser retornado algumas vezes pode não fazer sentido para um Search. Tenho em mente que uma tentativa de write pode ter acontecido e isso pode ter gerado um erro. * Agora que vocês já sabem disso olhem pro codigo de vocês e vejam se antes de um search em uma sessão de edicao vocês não tem uma oportunidade de fazer um write .
  5. - Porque chama-se posicional: porque você sempre atualiza o registro em que está posicionado * Diferente dos cursores de Search como vimos a pouco uma consulta em um cursor de Update nunca será atendida pelo cache ***** Tome cuidado com isso. Não misture as coisas. Operacoes em cursores de Update devem utilizar UpdateRow e DeleteRow. ***** Store e Delete devem ser utilizados em IFeature ou ITable
  6. Explorar um pouco isso pois não conheço direito - Ver (717) Simple - Point, Polyline that doesn't participate in Topology or Geometric Networks - Has performance benefits using Update Cursors - On Non Simple that is not true. Just a convenience. Because internally API has to certificate that all events are fired. (Use Store and Delete) Non Simple - Complex Features and Topology, Geometric Networks
  7. **** Nunca abra um cursor fora de uma sessao de edicao e depois utilize ele dentro de uma sessao de edicao. Sempre faça isso dentro ou fora. Nunca "Across". Isso porque os cursores são bind to a specic state no banco de dados. E esse estados estao ligados diretamente com as edições. Isso é EXTREMAMENTE importante. * A state is conected to a StartEditOperation * Cursor update está diretamente ligado a esse estado * Se você utiliza o mesmo cursor de update em diversas sessões de edição (boundaries) o estado a que ele está ligado está errado e pode ser um problema. * Go Back and check about it in your code * VERSIONED DATA - DON'T USE UPDATE CURSOR ACCROSS EDITOPERATION BOUNDARIES * SCOPE IS CRITICAL
  8. Over a hundred or more - Huge difference in performance - Combine it with buffering and flushing it the key to optimal performance - RE-Insertion (How many you can lose. How many you tolerate to re-insert? ) - Both need to be aware about errors: - InsertRow and Flush - Show the graph ---- Why this is importante? ---- Because during an insertrow call API checks if the buffer is full and fire a write to the database. Becuase of it is extremelly importnt to handle errosrs during both calls. ---- If you are not doing that these can explain strange errors thath you cant reproduce. you think thtat is your use r problem but it can be a flush here.
  9. ##### - Goes directy to the database (not use cache) - Evaluate in a edit session will flush all cached rows. Check your code and be aware of it. #####
  10. ###### That is allways a confusing stuff. How many of you know how this works? Really useful when you need just read only information! ######
  11. ####### - Dont pass it around! Look to your code and have sure about! #######
  12. ###### - Good example. 3x less than not using recycling ######
  13. ###### Use it when you need to edit or pass it around. Alert: - That doesnt mean that you cant use a recycling cursor inside a edit session. You Can! But remember only for read ! ######
  14. ##### - Marshall.ReleaseComObject #####
  15. Cursor FAQs - Ver Video Question: If I need to use a cursor inside an edit session, where should I create the cursor? Answer: ##### Inside the edit operation but not cross boundaries. That is very important! The code that is showed is not good code actually. It's a bad code. They make a joke about it. #####
  16. ###### Pode parecer estranho mas é recomendado fazer isso. Ver proximo slide. ######
  17. ###### ## Generally Seach cursors ## but if you are editing simple data you can get benefits using ## Update Cursors (Essencialmente porque eventos não são disparados) ######
  18. When to use the Schema Cache? • Beneficial when working with large static data models - • If the application opens and uses many classes - These should be opened at the start of the application and references maintained throughout the lifetime of the application How to use the Schema Cache • Enable schema cache before tables are opened - Calls to OpenFeatureClass, OpenTable, IName.Open will be optimized - Can enable schema caching at the factory level • Cache needs to be “fresh” - If in dynamic environments schema changes will not be visible until cache is refreshed. if (sCache.IsSchemaCacheStale(workspace)) sCache.RefreshSchemaCache(workspace); • Your responsibility to disable the cache - Must be disabled before releasing the workspace object that is cached
  19. #### They are going to more standable solutions. Now you have access to everything without ArcGIS. #### Forward compatibility - 10.0 can access a 10.1 data (except thing s stucked on 10.1) #### That can helps schema changes #### That can helps data exchange Simplified Schema - Motivation • Create more scalable catalog of dataset definitions • Support improved performance when browsing • Open the Geodatabase schema (XML vs. binary) • Support more extensible schema catalog • Support forward compatibility - Beginning at ArcGIS 10 SP2 -------------------------------------------------------------------------------- Simplified Schema - Caveats • Critical that your applications do not directly query the GDB system tables • You will not have to change your ArcObjects code - All Geodatabase APIs will continue to work seamlessly with new schema • New schema is not backward compatible - Pre ArcGIS 10 clients will not be able to connect to Geodatabases with the new schema
  20. ##### ## Cursors are the most misundertood thing on Geodb programming ## Keep this in mind. ## Use this presentation as a reference #####
  21. **** http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#//00010000010s000000 Scoping cursors to edit operations Cursors should be scoped to a single edit operation. This means a new cursor should be instantiated and released for each operation. This is very important when editing rows returned by a cursor because the rows are tied to a specific state of the geodatabase. Avoid using a cursor across multiple edit operations. Doing so can result in unexpected behavior and data loss. ****
  22. ##### Don't mix DML with DDL
  23. ##### There are some objects that are single instances. So be carefull about that if you wnatn to reuse variables like these example
  24. #### Nothing in a geodb is free. Almost everything cost. Every time you activated notification on RElClass everything related will slow down. Be aware about it. Don't enable everything by default. Nothing is free. Just keep this in mind!
  25. ##### ## Cursors are the most misundertood thing on Geodb programming ## Keep this in mind. ## Use this presentation as a reference #####