Filtrando dados para provedores simples
Em algumas situações, a réplica de destino requer apenas um subconjunto dos dados disponíveis na réplica de origem. Por exemplo, um vendedor pode exigir informações detalhadas somente dos produtos vendidos regularmente. Os provedores simples habilitam as réplicas para filtrar dados por meio da implementação de uma interface de filtragem. Com a filtragem de dados, você pode:
Reduzir a quantidade de dados enviada pela rede.
Reduzir a quantidade de espaço de armazenamento exigida na réplica. Isso é especialmente importante para dispositivos.
Fornecer partições de dados personalizadas com base nas necessidades individuais da réplica.
Evitar ou reduzir conflitos porque partições diferentes de dados podem ser enviadas a réplicas diferentes.
Lembre-se de que provedores simples não podem usar filtros personalizados ou podem ocorrer resultados inesperados. Os filtros personalizados são filtros que usam a classe CustomFilterInfo (para código gerenciado) ou a interface ICustomFilterInfo (para códigos não gerenciados).
Para filtrar dados, use as seguintes interfaces:
Código gerenciado: IFilteredSimpleSyncProvider, IRequestFilteredSync e ISupportFilteredSync
Código nativo: IFilteredSimpleSyncProvider, IRequestFilteredSync e ISupportFilteredSync
Exemplo de código gerenciado
O seguinte exemplo de código usa interfaces de negociação de filtro para determinar se um filtro específico deve ser usado durante uma sessão de sincronização. A negociação de filtro permite que um provedor de destino especifique que o provedor de origem deve usar um ou mais filtros durante a enumeração de alterações; o provedor de origem pode aceitar ou rejeitar um filtro. Se um provedor de origem não der suporte a um dos filtros solicitados, o provedor de destino poderá optar por receber todos os dados e fazer a filtragem sozinho. O Sync Framework chama os provedores adequadamente para negociar o uso de filtro.
public bool RequestFilter
{
set
{
_requestFilter = value;
}
}
private bool _requestFilter = false;
void IRequestFilteredSync.SpecifyFilter(FilterRequestCallback filterRequest)
{
// Request a filter only if this provider represents a filtered replica.
if (_requestFilter)
{
if (!filterRequest("TheFilter", FilteringType.CurrentItemsOnly))
{
throw new SyncInvalidOperationException("Could not agree on filter.");
}
}
}
bool ISupportFilteredSync.TryAddFilter(object filter, FilteringType filteringType)
{
if (!((string)filter).Equals("TheFilter"))
{
throw new Exception("Filter is incorrect");
}
// Remember the filter.
_filter = (string)filter;
return true;
}
private string _filter = "";
Public WriteOnly Property RequestFilter() As Boolean
Set(ByVal value As Boolean)
_requestFilter = value
End Set
End Property
Private _requestFilter As Boolean = False
Private Sub SpecifyFilter(ByVal filterRequest As FilterRequestCallback) Implements IRequestFilteredSync.SpecifyFilter
' Request a filter only if this provider represents a filtered replica.
If _requestFilter Then
If Not filterRequest("TheFilter", FilteringType.CurrentItemsOnly) Then
Throw New SyncInvalidOperationException("Could not agree on filter.")
End If
End If
End Sub
Private Function TryAddFilter(ByVal filter As Object, ByVal filteringType As FilteringType) As Boolean Implements ISupportFilteredSync.TryAddFilter
If Not DirectCast(filter, String).Equals("TheFilter") Then
Throw New Exception("Filter is incorrect")
End If
' Remember the filter.
_filter = DirectCast(filter, String)
Return True
End Function
Private _filter As String = ""
O exemplo de código a seguir especifica primeiro uma opção de filtro None. Isso significa que os itens devem ser filtrados mesmo se forem conhecidos do destino. O exemplo de código implementa, em seguida, o método IsItemInFilterScope, que filtra itens com base em um dos valores de campo de item. Depois que o filtro é definido, o exemplo de código implementa o método UseFilterThisSession. Isso permite que um aplicativo especifique se a filtragem deve ser usada por sessão.
SimpleSyncProviderFilterOptions IFilteredSimpleSyncProvider.FilterOptions
{
get
{
return SimpleSyncProviderFilterOptions.None;
}
}
bool IFilteredSimpleSyncProvider.IsItemInFilterScope(ItemFieldDictionary KeyAndVersion)
{
ulong itemId = (ulong)KeyAndVersion[1].Value;
ItemData itemData = _store.Get(itemId);
if (itemData["data"] == "3333")
{
return false;
}
return true;
}
bool IFilteredSimpleSyncProvider.UseFilterThisSession
{
get
{
// Indicate whether a filter has been requested and agreed upon for this session.
return ("" != _filter);
}
}
Private ReadOnly Property FilterOptions() As SimpleSyncProviderFilterOptions Implements IFilteredSimpleSyncProvider.FilterOptions
Get
Return SimpleSyncProviderFilterOptions.None
End Get
End Property
Private Function IsItemInFilterScope(ByVal KeyAndVersion As ItemFieldDictionary) As Boolean Implements IFilteredSimpleSyncProvider.IsItemInFilterScope
Dim itemId As ULong = KeyAndVersion(1).Value
Dim data As ItemData = _store.Get(itemId)
If data("data") Is "3333" Then
Return False
End If
Return True
End Function
Private ReadOnly Property UseFilterThisSession() As Boolean Implements IFilteredSimpleSyncProvider.UseFilterThisSession
Get
' Indicate whether a filter has been requested and agreed upon for this session.
Return "" Is _filter
End Get
End Property