Сериализация объектов и передача их на другую машину
Обычно делается, что сериализатор помнит какие объекты он уже сохранил, соответственно при повторных save-ах того же объекта, сохраняется только ссылка.
Например, таким образом сериализация устроена в MFC
в Java лечится, например, с помощью readResolve
Список, возвращаемый функцией
public ArrayList My
{
ArrayList s1 = new ArrayList;
s1.Add(1);
ArrayList s2 = new ArrayList;
s2.Add(2);
ArrayList s3 = new ArrayList;
s3.Add(3);
ArrayList p1 = new ArrayList;
p1.Add(s1);
p1.Add(s2);
ArrayList p2 = new ArrayList;
p2.Add(s2);
p2.Add(s3);
ArrayList result = new ArrayList;
result.Add(p1);
result.Add(p2);
return result;
}
по умолчанию сериализуется в
<ArrayOfAnyType xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/">
<anyType xsi:type="ArrayOfAnyType">
<anyType xsi:type="ArrayOfAnyType">
<anyType xsi:type="xsd:int">1</anyType>
</anyType>
<anyType xsi:type="ArrayOfAnyType">
<anyType xsi:type="xsd:int">2</anyType>
</anyType>
</anyType>
<anyType xsi:type="ArrayOfAnyType">
<anyType xsi:type="ArrayOfAnyType">
<anyType xsi:type="xsd:int">2</anyType>
</anyType>
<anyType xsi:type="ArrayOfAnyType">
<anyType xsi:type="xsd:int">3</anyType>
</anyType>
</anyType>
</ArrayOfAnyType>
видно, что двойка повторилась два раза.
с описаной ситуацией сериализатор еще может справиться, а если нужно передать две порции по 5 книг?
Если есть две порции, то категории будут два раза передаваться и с DataSet-ом
точнее второй раз можно передать только те категори,и которые связана с передаваемыми книгами
Есть подозрение, что
по умолчанию
это как раз таки не по умолчанию. Скорее всего в ArrayList дефолтная сериализация переопределена.
А если вместо ArrayList использовать массивы, то же самое получается?
Я правильно понял, что ты использовал XmlSerializer?
> точнее второй раз можно передать только те категори,и которые связана с передаваемыми книгами
Такой функционал можно поддержать и на бизнес-entities-ах.
Я правильно понял, что ты использовал XmlSerializer?
я создал простейший Web Service, в IE можно посмотреть как передается объект, наверное по-умолчанию используется XmlSerializer.
В bin-формате по-другому?
Marriage - это merge?
да.
Такой функционал можно поддержать и на бизнес-entities-ах.
Как? (то что можно всё, это понятно). Если ничего дополнительного не делать, то одна категория может превратиться в несколько объектов, и, например, при изменении имени категории придется менять свойство у нескольких объектов.
Попробуй, в примере, вместо чисел использовать объекты, есть подозрение, что числа всегда сохраняются по значению.
ps
soap-serializer и bin-serializer - одиннаково устроены, и умеют правильно сохранять объектные графы.
xml-serializer - вообще любую ссылку рассматривает как ссылку "parent<->child"
при save, если объект уже сохранялся, то вместо самого объекта сохраняется ссылка на него (некий id)
при лоад-t, если встречается ссылка, то востанавливается ссылка на реальный объект.
Попробуй, в примере, вместо чисел использовать объекты, есть подозрение, что числа всегда сохраняются по значению
в моем примере специально введено дополнительное вложение, чтобы были объекты
s2 это объект
ок, вроде не сложно, но всё-таки дополнительные действия, я не против и такого подхода
Действия ровно те же самые, что и при использовании data.set-ов: взять готовую библиотечку и заюзать
при использовании soap-formatter-а генерится следующий xml:
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<a1:ArrayList id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/ns/System.Collections">
<_items href="#ref-2"/>
<_size>2</_size>
<_version>2</_version>
</a1:ArrayList>
<SOAP-ENC:Array id="ref-2" SOAP-ENC:arrayType="xsd:anyType[16]">
<item href="#ref-3"/>
<item href="#ref-4"/>
</SOAP-ENC:Array>
<a1:ArrayList id="ref-3" xmlns:a1="http://schemas.microsoft.com/clr/ns/System.Collections">
<_items href="#ref-5"/>
<_size>2</_size>
<_version>2</_version>
</a1:ArrayList>
<a1:ArrayList id="ref-4" xmlns:a1="http://schemas.microsoft.com/clr/ns/System.Collections">
<_items href="#ref-6"/>
<_size>2</_size>
<_version>2</_version>
</a1:ArrayList>
<SOAP-ENC:Array id="ref-5" SOAP-ENC:arrayType="xsd:anyType[16]">
<item href="#ref-7"/>
<item href="#ref-8"/>
</SOAP-ENC:Array>
<SOAP-ENC:Array id="ref-6" SOAP-ENC:arrayType="xsd:anyType[16]">
<item href="#ref-8"/>
<item href="#ref-9"/>
</SOAP-ENC:Array>
<a1:ArrayList id="ref-7" xmlns:a1="http://schemas.microsoft.com/clr/ns/System.Collections">
<_items href="#ref-10"/>
<_size>1</_size>
<_version>1</_version>
</a1:ArrayList>
<a1:ArrayList id="ref-8" xmlns:a1="http://schemas.microsoft.com/clr/ns/System.Collections">
<_items href="#ref-11"/>
<_size>1</_size>
<_version>1</_version>
</a1:ArrayList>
<a1:ArrayList id="ref-9" xmlns:a1="http://schemas.microsoft.com/clr/ns/System.Collections">
<_items href="#ref-12"/>
<_size>1</_size>
<_version>1</_version>
</a1:ArrayList>
<SOAP-ENC:Array id="ref-10" SOAP-ENC:arrayType="xsd:anyType[16]">
<item xsi:type="xsd:int">1</item>
</SOAP-ENC:Array>
<SOAP-ENC:Array id="ref-11" SOAP-ENC:arrayType="xsd:anyType[16]">
<item xsi:type="xsd:int">2</item>
</SOAP-ENC:Array>
<SOAP-ENC:Array id="ref-12" SOAP-ENC:arrayType="xsd:anyType[16]">
<item xsi:type="xsd:int">3</item>
</SOAP-ENC:Array>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
static public object[] My2
{
object[] s1 = new object[]{1};
object[] s2 = new object[]{2};
object[] s3 = new object[]{3};
object[] p1 = new object[]{s1, s2};
object[] p2 = new object[]{s2, s3};
return new object[]{p1, p2};
}
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:anyType[2]">
<item href="#ref-2"/>
<item href="#ref-3"/>
</SOAP-ENC:Array>
<SOAP-ENC:Array id="ref-2" SOAP-ENC:arrayType="xsd:anyType[2]">
<item href="#ref-4"/>
<item href="#ref-5"/>
</SOAP-ENC:Array>
<SOAP-ENC:Array id="ref-3" SOAP-ENC:arrayType="xsd:anyType[2]">
<item href="#ref-5"/>
<item href="#ref-6"/>
</SOAP-ENC:Array>
<SOAP-ENC:Array id="ref-4" SOAP-ENC:arrayType="xsd:anyType[1]">
<item xsi:type="xsd:int">1</item>
</SOAP-ENC:Array>
<SOAP-ENC:Array id="ref-5" SOAP-ENC:arrayType="xsd:anyType[1]">
<item xsi:type="xsd:int">2</item>
</SOAP-ENC:Array>
<SOAP-ENC:Array id="ref-6" SOAP-ENC:arrayType="xsd:anyType[1]">
<item xsi:type="xsd:int">3</item>
</SOAP-ENC:Array>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Оставить комментарий
6yrop
Пусть есть сущности связанные "многие к одному", например, книги и их категории.public class Book
{
public string Title;
public CategoryType Category;
}
public class CategoryType
{
public string Name;
}
Как передать 10 книг с сервера на клиента? Если сериализовать каждый объект типа Book отдельно, то некоторые категории будут сериализованы несколько раз, и на клиенте будут восстановлены в два разных объекта. Т.е. нужно сериализовать всю коллекцию из 10 книг сразу и устанавливать поле Book.Category извне (по отношению в классу Book).
А вот если пользоваться data-centric реляционным подходом DataSet-ов, то такой проблемы не возникает.