Я использую XmlDictionaryWriter для сериализации объектов в базу данных с помощью сериализатора контракта данных.
Он отлично работает, размер и скорость в 2 раза лучше, чем при использовании text / xml.
Однако мне придется иметь дело с огромным количеством записей в моей базе данных, где любые дополнительные байты напрямую переводятся в гигабайты размера БД.
Вот почему я бы хотел еще больше уменьшить размер, используя словарь XML.
Как мне это сделать?
Я вижу, что статический метод XmlDictionaryWriter.CreateBinaryWriter принимает 2-й параметр типа IXmlDictionary. В MSDN написано «XmlDictionary для использования в качестве общего словаря».
Сначала я попытался использовать системную реализацию:
XmlDictionary dict = new XmlDictionary();
string[] dictEntries = new string[]
{
"http://schemas.datacontract.org/2004/07/MyContracts",
"http://www.w3.org/2001/XMLSchema-instance",
"MyElementName1",
"MyElementName2",
"MyElementName3",
};
foreach ( string s in dictEntries )
dict.Add( s );
В результате .NET Framework полностью игнорирует словарь и по-прежнему вставляет вышеуказанные строки в виде обычного текста, а не просто ссылается на соответствующую запись словаря.
Затем я создал собственную реализацию IXmlDictionary:
class MyDictionary : IXmlDictionary
{
Dictionary<int, string> values = new Dictionary<int, string>();
Dictionary<string, int> keys = new Dictionary<string, int>();
MyDictionary()
{
string[] dictEntries = new string[]
{
"http://schemas.datacontract.org/2004/07/MyContracts",
"http://www.w3.org/2001/XMLSchema-instance",
"MyElementName1",
"MyElementName2",
"MyElementName3",
};
foreach ( var s in dictEntries )
this.Add( s );
}
static IXmlDictionary s_instance = new MyDictionary();
public static IXmlDictionary instance { get { return s_instance; } }
void Add( string val )
{
if ( keys.ContainsKey( val ) )
return;
int id = values.Count + 1;
values.Add( id, val );
keys.Add( val, id );
}
bool IXmlDictionary.TryLookup( XmlDictionaryString value, out XmlDictionaryString result )
{
if ( value.Dictionary == this )
{
result = value;
return true;
}
return this.TryLookup( value.Value, out result );
}
bool IXmlDictionary.TryLookup( int key, out XmlDictionaryString result )
{
string res;
if ( !values.TryGetValue( key, out res ) )
{
result = null;
return false;
}
result = new XmlDictionaryString( this, res, key );
return true;
}
public bool /* IXmlDictionary. */ TryLookup( string value, out XmlDictionaryString result )
{
int key;
if ( !keys.TryGetValue( value, out key ) )
{
result = null;
return false;
}
result = new XmlDictionaryString( this, value, key );
return true;
}
}
Результат - мои методы TryLookup называются OK, однако DataContractSerializer.WriteObject создает пустой документ.
Как использовать общедоступный словарь?
Заранее спасибо!
P.S. Я не хочу связываться с XmlBinaryReaderSession / XmlBinaryWriterSession: у меня нет "сессий", вместо этого у меня есть база данных объемом 10 ГБ +, к которой одновременно обращается множество потоков То, что я хочу, это просто статический предопределенный словарь.
Обновление: ОК Я понял, что мне просто нужно вызвать "XmlDictionaryWriter.Flush". Единственный оставшийся вопрос - почему предоставляемая системой реализация IXmlDictionary не работает должным образом?