Identificatore e mapping di proprietà
Eseguire il mapping dei concetti generici alle parti e alle proprietà dell'identificatore è più complesso dei tipi di mapping, come descritto Mapping dei tipiin. Ad esempio, oltre a occupare b: il problema g da risolvere, come avviene con mapping dei tipi, esistono la questione aggiunta di mapping dei dati. Gestire i dati è necessario eseguire il mapping della conversione corretta dei dati dati-database di origine-specifici al formato previsto dai concetti generici.
Questo e nelle sezioni seguenti finora, in è più difficile di mapping dei dati e quindi applicheremo la discussione alle varie versioni di b: problema g :
Mapping dei dati
Identificatore e mapping di proprietà
Mapping dei dati a 1:1
1: mapping dei dati g
b: 1 Mapping dei dati
b: mapping dei dati g
Mapping dei dati
Il mapping dei dati elencate le difficoltà di due tipi principali. Innanzitutto, è la questione dei tipi di dati in conflitto come, ad esempio, quando i valori true e false di Booleano-tipo vengono memorizzati come stringhe. In secondo luogo, è il problema dei diversi valori che rappresentano gli stessi dati come, ad esempio, quando si utilizzano i valori di indice di stringa “0 ", “1 " e “2 " accanto ai valori stringa analoghi “NOT CHIAVE„, “UNIVOCI„ e “PRIMARI„.
Per garantire una maggiore flessibilità, un provider di dati può specificare una serie di passaggi di conversione che, una volta seguito, di convertire un valore dati-database di origine-specifico a un valore coerente con un tipo mappato generico. Ogni passaggio di conversione può implementare una delle seguenti azioni:
ChangeType
Per eseguire una conversione di tipi al valore corrente, chiamare il metodo Convert.ChangeTypedi .NET Framework. Spetta al provider di dati per garantire che il valore corrente è di un tipo che può essere convertito ovvero che implementa l'interfaccia di IConvertible Interface ) contenente i dati che possono essere convertiti correttamente.Match
Per analizzare una rappresentazione di stringa del valore corrente, utilizzare un'espressione regolare.NET. Questa operazione produce un set di valori correnti uguali a validità di ogni gruppo corrispondente (o se nessun gruppo è specificato, il valore corrispondente. Se non viene rilevata alcuna corrispondenza, un set predefinito di nuovi valori correnti specificati dal provider viene scelto. Se il provider è una corrispondenza viene eseguita sempre, i valori predefiniti non deve essere specificata.Split
Per analizzare una rappresentazione di stringa del valore corrente in parti separati da una stringa che corrisponde all'espressione, viene utilizzata un'espressione regolare.NET. Questa operazione produce un set di valori correnti uguali ai valori di ciascuna parte della stringa.Replace
Per analizzare una rappresentazione di stringa del valore corrente e quindi utilizzare un modello di sostituzione per compilare un nuovo valore corrente in base ai valori di gruppo corrispondenti, utilizzare un'espressione regolare.NET.Format
Per compilare una stringa in base ai valori correnti, utilizzare una stringa di formato.NET. L'insieme di valori correnti sono passati come parametri di formato alla chiamata di funzione di String.Format , che consente di fare riferimento al set di valori correnti utilizzando {0}, {1}, e così via.Calculate
Per compilare un nuovo valore in base ai valori correnti, utilizzare un'espressione di ADO.NET . La stringa dell'espressione in primo luogo viene passata con String.Format con l'insieme di valori correnti come parametri di formato, che consente di fare riferimento a tali valori utilizzando {0}, {1}, e così via. I valori di riferimento in questo modo richiede l'utilizzo di un carattere di escape quando sono presenti parentesi graffe nella stringa a cui si fa riferimento.CallMapper
Questo elemento deve essere l'ultima conversione nel set di passaggi di conversione. Specifica un metodo personalizzato denominato per convertire il valore del membro mappato e contiene anche il tipo che implementa questo metodo.
Per ognuna delle azioni in precedenza, uno o più valori correnti possono contenere dati che l'azione può fare riferimento. Quando una conversione inizia, un valore corrente è uguale al valore dati-database di origine-specifico. Mentre i passaggi di conversione continuazione, questi valori correnti vengono modificati, finalize mentre un valore convertito finale.
L'architettura del conversione-passaggio consente ai provider di dati modificare eliminare tutti i dati dati-database di origine-specifici nel tipo e nel formato appropriati per il tipo mappato generico rappresenta.
Identificatore e mapping di proprietà
Il problema di b: g per le parti e le proprietà dell'identificatore si verifica perché è possibile includere dati che vengono compilati o analizzati da altri dati. Ad esempio, un tipo di dati della colonna può essere costituita da un nome di tipo, una lunghezza, una precisione e di una scala. Alcuni, tutti, oppure none questi dati fanno parte di una singola proprietà. Il problema di b: g si verifica quando gli identificatori o le proprietà generici equivalente non vengono compressi.
Ad esempio, si consideri un database SQL Server che espone il tipo di dati di una colonna come singola proprietà che include il nome del tipo, la lunghezza, la correttezza e la scala. Se un tipo di dati mappato generico del tipo di proprietà prevede un determinato formato di tali informazioni e SQL viene visualizzato solo in base a questo formato, il mapping è 1:1 e non determina alcun problema (vedere l'esempio di codice, in). Di altra parte, se c " è un tipo di dati mappato generico, lunghezza, precisione e scala dei tipi di proprietà (che è molto più probabile), si dispone di un 1:g mapping-che è, una singola proprietà dati-database di origine-specifica (tipo di dati) che rappresentano più proprietà generica concetto-in questo caso, tipo di dati, lunghezza, precisione e scala. Vedere l'esempio di codice riportato di seguito.
Adottare per un altro esempio il caso di un database che dispone di proprietà dati-database di origine-specifiche IsPrimaryKey e IsUniqueKey il tipo di indice. Si supponga, inoltre, che vi sia un concetto generico della proprietà, IndexKeyType, che utilizza un vettore di bit per specificare () se l'indice è una chiave e (b) in tal caso, il tipo di chiave. In questo scenario indice di chiave potrebbe non essere key=0, key=1 univoco e key=2 primario). In tale scenario, è stato b: 1 mapping, in cui le proprietà dati-database di origine-specifiche più sono rappresentate da un singolo tipo generico della proprietà (vedere l'esempio di codice, come indicato di seguito.
Infine, si consideri un esempio del caso più complesso, in cui esista tipo di dati dati-database di origine-specifico e DataTypeNumInfo delle proprietà. La proprietà del tipo di dati include un nome e una lunghezza e la proprietà di DataTypeNumInfo include la correttezza e la scala. Si supponga che siano proprietà generiche DataTypeName e DataTypeInfo. La proprietà di DataTypeName include solo un nome e la proprietà di DataTypeInfo include la lunghezza, la correttezza e la scala. Si tratta di b: g che esegue il mapping, in cui le proprietà dati-database di origine-specifiche più sono rappresentate dalle proprietà generiche più.
Di seguito vengono riepilogate ed esempi di codice di ognuno degli scenari del mapping di proprietà e dell'identificatore.
Mapping dei dati a 1:1
Il mapping uno-a-uno è il caso più semplice e richiede una quantità minima di lavoro. Un provider di dati contiene una singola parte o proprietà dati-database di origine-specifica dell'identificatore che eseguono il mapping a una singola parte dell'identificatore o concetto generica della proprietà come nell'esempio seguente:
<Type name="Table" preferredOrdering="Database, Schema, Name">
...
<Properties>
...
<Property name="ObjectType" type="System.String" />
</Properties>
</Type>
<MappedType name="Table" underlyingType="Table">
...
<Properties>
<Property name="IsSystemObject" underlyingMember="ObjectType">
<Conversion>
<Calculate expr="IIF({0}=SYSTEM,true,false") exprType="System.Boolean" />
</Conversion>
</Property>
</Properties>
</MappedType>
In questo esempio, una proprietà dati-database di origine-specifica, ObjectType, può contenere due valori stringa, “a„ e “SYSTEM„. Mapping di tali informazioni al tipo mappato generico IsSystemObject, definito come valore booleano. Pertanto, un passaggio di conversione calcola un'espressione booleana in base al valore stringa dati-database di origine-specifico.
1: mapping dei dati g
il 1: il caso g è leggermente più complesso. Un provider di dati contiene una singola parte o proprietà dati-database di origine-specifica dell'identificatore che eseguono il mapping alle parti generiche più o le proprietà dell'identificatore. Per riuscire, il provider di dati viene applicato un mapping specificando le proprietà generiche con lo stesso valore di underlyingMember, come illustrato nel codice seguente:
<Type name="Column" preferredOrdering="Database, Schema, Table, Id">
...
<Properties>
...
<Property name="DataType" type="System.String" />
</Properties>
</Type>
<MappedType name="TableColumn" underlyingType="Column">
...
<Properties>
<Property name="DataType" underlyingMember="DataType">
<Conversion>
<Match regex="^[^(]+" />
</Conversion>
</Property>
<Property name="Length" underlyingMember="DataType">
<Conversion>
<Match regex="(?<=^CHAR\(|^VARCHAR\()\d+">
<Defaults>
<Default value="0" />
</Defaults>
</Match>
<ChangeType type="System.Int32" />
</Conversion>
</Property>
<Property name="Precision" underlyingMember="DataType">
<Conversion>
<Match regex="(?<=^NUMERIC\()\d+">
<Defaults>
<Default value="0" />
</Defaults>
</Match>
<ChangeType type="System.Int32" />
</Conversion>
</Property>
</Properties>
</MappedType>
in questo esempio, una proprietà dati-database di origine-specifica, tipo di dati, contiene le informazioni per tre proprietà generiche. Inizia con il nome del tipo di dati e scegliere tra parentesi contiene informazioni sulla lunghezza dei tipi di carattere e quindi sulla correttezza del tipo numerico.
Per recuperare un valore per il tipo di dati mappato generico della proprietà, il provider deve estrarre la prima parte del valore dati-database di origine-specifico utilizzando un'espressione regolare semplice che corrisponde alle parole a una parentesi aperta.
Per recuperare un valore per la lunghezza mappata generica della proprietà, il provider deve estrarre il primo numero tra parentesi, ma solo se è un tipo di dati carattere. In caso contrario, il valore è zero. L'espressione regolare specificata viene eseguita in collaborazione con il valore predefinito visualizzato. Una seconda azione converte la stringa estratta al tipo corretto previsto dal concetto generico della proprietà.
Per recuperare un valore per la precisione mappata generica della proprietà, il provider deve estrarre il primo numero tra parentesi, ma solo se è un tipo di dati numerico. In caso contrario, il valore è zero. L'espressione regolare specificata viene eseguita in collaborazione con il valore predefinito visualizzato. Una seconda azione converte la stringa estratta al tipo corretto previsto dal concetto generico della proprietà.
b: 1 Mapping dei dati
In questo caso è richiesto un poco più lavoro che il 1: mapping g . In questo scenario, un provider di dati con le parti dati-database di origine-specifiche più proprietà o dell'identificatore che eseguono il mapping a una singola parte dell'identificatore o concetto generica della proprietà. I provider di dati si applicano questo mapping specificando un valore delimitato da virgole per l'attributo di underlyingMember dell'elemento proprietà contenente tutte le proprietà dati-database di origine-specifiche che eseguono il mapping alla proprietà generica, come illustrato nell'esempio di codice:
<Type name="Index" preferredOrdering="Database, Schema, Table, Name">
...
<Properties>
<Property name="IsUniqueKey" type="System.Boolean" />
<Property name="IsPrimaryKey" type="System.Boolean" />
...
</Properties>
</Type>
<MappedType name="TableIndex" underlyingType="Index">
...
<Properties>
<Property name="DataType" underlyingMember="DataType">
<Conversion>
<Match regex="^[^(]+" />
</Conversion>
</Property>
<Property name="IndexKeyType" underlyingMember="IsUniqueKey,IsPrimaryKey">
<Conversion>
<Calculate expr="IIF({0}=true,
IIF({1}=true,PRIMARY,UNIQUE),
NONE)"
type="System.String" />
</Conversion>
</Property>
<Property name="Precision" underlyingMember="DataType">
<Conversion>
<Match regex="(?<=^NUMERIC\()\d+">
<Defaults>
<Default value="0" />
</Defaults>
</Match>
<ChangeType type="System.Int32" />
</Conversion>
</Property>
</Properties>
</MappedType>
In questo esempio, le proprietà dati-database di origine-specifiche IsUniqueKey e IsPrimaryKey sono true o false base a un indice è una chiave o non e in caso positivo, il tipo. La proprietà generica IndexKeyType è una stringa che è uguale a NONE, UNIVOCHE, o PRIMARIE.
Entrambe le proprietà dati-database di origine-specifiche sono necessarie per fornire informazioni complete per la proprietà generica. Di conseguenza, il provider deve unire il contenuto più proprietà in una e una conversione deve verificarsi.
b: mapping dei dati g
In questo caso presenta una combinazione di 1: g e b: 1 mapping. Un provider di dati con le parti dati-database di origine-specifiche più proprietà o dell'identificatore che eseguono il mapping alle parti generiche più o le proprietà dell'identificatore. I provider di dati implementano questo mapping specificando più proprietà di origine dati mappate alle proprietà generiche più, come illustrato nel seguente esempio:
<Type name="Column" preferredOrdering="Database, Schema, Table, Id">
...
<Properties>
<Property name="DataType" type="System.String" />
<Property name="DataTypeNumInfo" type="System.String" />
...
</Properties>
</Type>
<MappedType name="TableColumn" underlyingType="Column">
...
<Properties>
<Property name="DataTypeName" underlyingMember="DataType">
<Conversion>
<Match regex="^[^(]+" />
</Conversion>
</Property>
<Property name="DataTypeInfo" underlyingMember="DataType,DataTypeNumInfo">
<Conversion>
<Format string="{0}#{1}" />
<Replace regex="\((\d+)\)#(\d+),(\d+)" pattern="$1,$2,$3" />
</Conversion>
</Property>
...
</Properties>
</MappedType>
In questo esempio, il tipo di dati dati-database di origine-specifico e DataTypeNumInfo delle proprietà forniscono un tipo di dati con lunghezza, la correttezza e adattamento, rispettivamente. La proprietà generica DataTypeName contiene solo il nome e DataTypeInfo contiene la lunghezza, la correttezza e le informazioni di ridimensionamento.
Per recuperare un valore per la proprietà generica DataTypeName, il provider deve estrarre la prima parte del tipo di dati dati-database di origine-specifico della proprietà utilizzando un'espressione regolare semplice che corrisponde alle parole fino a una parentesi aperta.
Per recuperare un valore per la proprietà generica DataTypeInfo, il provider di dati deve estrarre la seconda parte del tipo di dati dati-database di origine-specifico di proprietà e le due parti della proprietà dati-database di origine-specifica DataTypeNumInfo quindi incollare questi insieme in formato corretto. Questa operazione viene eseguita in primo luogo concatenando entrambe le proprietà in una singola stringa e quindi utilizzando un'espressione regolare corrispondente alla lunghezza, la correttezza e le informazioni di ridimensionamento. Infine, il provider di dati esegue un'operazione di sostituzione per creare una nuova stringa singola con queste informazioni nel formato.
Vedere anche
Concetti
Identificatori di tipo e proprietà dell'oggetto mapping ai tipi generici