使用 DataContractSerializer 序列化 DataSet 时保留 DataRowState

发布于 2024-09-02 09:20:14 字数 216 浏览 8 评论 0原文

由于各种原因,我必须将类型化数据集发送到 WCF 服务端点。这工作得很好,除了在反序列化时,每个 DataTable 中每一行的 RowState 都设置为“已添加”,无论它们在客户端上是什么。如果我将序列化流写入文件,我会发现 RowState 不是序列化数据的一部分。如何添加它以便可以跨服务边界保留 RowState?我认为这并不重要,但客户端进程正在运行 .net 3.5,而服务进程正在运行 .net 4.0

For various reasons I am having to send a typed dataset to a WCF service endpoint. This works fine except that upon Deserializing, the RowState of each row in each DataTable is set to 'Added', regardless of what they were on the client. If I write the serialized stream out to a file, I see that the RowState is not part of the Serialized data. How can I add this so that I can preserve the RowState across service boundaries? Not that I think it matters, but the client process is running .net 3.5 while the service process is running .net 4.0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

肥爪爪 2024-09-09 09:20:14

我也遇到了这个问题,并找到了一个非常简单的解决方案:
不要使用数据集对象的“WriteXml”方法,而是使用 BinaryFormatter“手动”序列化对象:

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

反序列化时,对象处于与之前完全相同的状态,包括行状态数据。

I had this problem also, and found a very simple solution for it:
Instead of using the dataset object's "WriteXml" method, serialize the object 'manually' using a BinaryFormatter:

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

When you deserialize, the object is in the exact same state as before, including the rowstate data.

转瞬即逝 2024-09-09 09:20:14

下面是 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;
    }
}

如您所见,您可能无法对其值执行任何操作,因为它是计算出来的,而不仅仅是存储的。最简单的解决方案可能是仅向数据集中添加另一列,其中包含行的状态。


(为什么它总是计算出值Added?很可能是因为当您的序列化数据集在服务器上重新水合时,会创建新行并将其添加到数据集中 - 因此该值实际上是正确的如果您按照上述建议向数据集添加另一列,则需要更改服务器代码才能检查和处理它 - 如果您打算进行此类更改,那么也许值得这样做。整个事情并重新编码该服务以使用正确的可序列化 DTO?)。

Here is the code for the RowState property:

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;
    }
}

as you can see, there may be nothing you can do about its value, because it is calculated rather than just stored. The easiest solution may be to just add another column to the DataSet which contains the state of the row.


(Why does it always calculate out to the value Added? Most likely because when your serialized dataset is rehydrated back on the server, new rows are created and added to the dataset - so the value is quite literally true. If you follow the above suggestion to add another column to the dataset, that will require a change to the server code to be able to examine and process it - if you are going to make that sort of change then maybe it is worth doing the whole thing and recode that service to use proper serializable DTOs instead?).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文