Сохранение DataRowState при сериализации DataSet с использованием DataContractSerializer - PullRequest
2 голосов
/ 25 мая 2010

По разным причинам мне приходится отправлять типизированный набор данных в конечную точку службы WCF. Это работает нормально, за исключением того, что при десериализации RowState каждой строки в каждой DataTable устанавливается на «Добавлен», независимо от того, что они были на клиенте. Если я записываю сериализованный поток в файл, я вижу, что RowState не является частью сериализованных данных. Как я могу добавить это, чтобы я мог сохранить RowState через границы службы? Не то чтобы я думаю, что это имеет значение, но клиентский процесс работает с .net 3.5, а сервисный процесс работает с .net 4.0

Ответы [ 2 ]

2 голосов
/ 12 июля 2011

У меня тоже была эта проблема, и я нашел очень простое решение: Вместо использования метода WriteXml объекта набора данных сериализуйте объект «вручную», используя BinaryFormatter:

BinaryFormatter bf = new BinaryFormatter();
using(FileStream fs = File.Open("datastore.dat", FileMode.Create, FileAccess.Write))
{
  bf.Serialize(fs, ds);
}

При десериализации объект находится в том же состоянии, что и раньше, включая данные состояния строки.

1 голос
/ 25 мая 2010

Вот код для свойства RowState:

public DataRowState RowState
{
    get
    {
        if (this.oldRecord == this.newRecord)
        {
            if (this.oldRecord == -1)
            {
                return DataRowState.Detached;
            }
            if (0 < this._columns.ColumnsImplementingIChangeTrackingCount)
            {
                foreach (DataColumn column in this._columns.ColumnsImplementingIChangeTracking)
                {
                    object obj2 = this[column];
                    if ((DBNull.Value != obj2) && ((IChangeTracking)obj2).IsChanged)
                    {
                        return DataRowState.Modified;
                    }
                }
            }
            return DataRowState.Unchanged;
        }
        if (this.oldRecord == -1)
        {
            return DataRowState.Added;
        }
        if (this.newRecord == -1)
        {
            return DataRowState.Deleted;
        }
        return DataRowState.Modified;
    }
}

как видите, вы ничего не можете сделать с его значением, потому что оно вычисляется, а не просто сохраняется. Самым простым решением может быть просто добавить еще один столбец в DataSet, который содержит состояние строки.


(Почему он всегда вычисляется до значения Добавлено ? Скорее всего, потому что, когда ваш сериализованный набор данных повторно гидратируется на сервере, новые строки создаются и добавляются в набор данных - так что значение довольно буквально верно. Если вы последуете приведенному выше предложению добавить еще один столбец в набор данных, это потребует изменения серверного кода, чтобы можно было его изучить и обработать - если вы собираетесь внести такого рода изменения, то, возможно, оно того стоит делать все это и перекодировать этот сервис, чтобы вместо него использовать правильные сериализуемые DTO?).

...