2009-08-11 39 views
9

Tôi có dữ liệu đã được lưu trữ sử dụng serialization nhị phân cho các lớp sau đây:Làm thế nào để tôi deserialize dữ liệu cũ cho một loại đã thay đổi?

[Serializable] 
public abstract class BaseBusinessObject 
{ 
    private NameValueCollection _fieldErrors = new NameValueCollection(); 

    protected virtual NameValueCollection FieldErrors 
    { 
     get { return _fieldErrors; } 
     set { _fieldErrors = value; } 
    } 

    ... 
} 

Tại một số điểm, lớp học đã được thay đổi như sau:

[Serializable] 
public abstract class BaseBusinessObject 
{ 
    private Dictionary<string, string> _fieldErrors = new Dictionary<string, string>(); 

    protected virtual Dictionary<string, string> FieldErrors 
    { 
     get { return _fieldErrors; } 
     set { _fieldErrors = value; } 
    } 

    ... 
} 

này đang gây ra những vấn đề deserializing dữ liệu cũ.

Suy nghĩ đầu tiên của tôi là triển khai ISerializable, nhưng lớp này có nhiều thuộc tính cũng như hàng trăm lớp kế thừa mà tôi sẽ phải triển khai thực hiện điều này.

Tôi muốn thay đổi dữ liệu cũ để phù hợp với cấu trúc hiện tại trong quá trình deserialization hoặc có một cách sạch sẽ để nâng cấp dữ liệu cũ.

Trả lời

4

Thêm mới _ fieldErrors dưới tên khác, giả sử _fieldErrors2 và đặt thành [Optional]. Sau đó, triển khai phương thức [OnDeserialized] Sao chép dữ liệu từ _fieldErrors đến _fieldErrors2 (nếu có) và xóa _fieldErrors.

+0

Điều này cung cấp cách tiếp cận thực tế nhất cho nhu cầu của tôi, nhưng tôi đã đi xuống một tuyến đường khác. – ramnik

3

Nếu dữ liệu chỉ được sử dụng trong nội bộ, suy nghĩ đầu tiên của tôi là viết một số mã đơn giản để loại bỏ dữ liệu nhị phân của bạn bằng cách sử dụng "NameValueCollection" cũ, ánh xạ nó vào Dictionnary và sắp xếp lại nó. Ngay cả khi nó sẽ mất một vài ngày để xử lý tất cả các dữ liệu, nó không có vẻ giá trị nó để thực hiện một bản vá trên mã mới của bạn để hỗ trợ các dữ liệu cũ.

Thậm chí nếu nó không chỉ được sử dụng trong nội bộ, một nhà nhập khẩu có vẻ như là cách đơn giản nhất để đi.

2

Thêm vào lời khuyên hữu ích của OlivierD, tôi khuyên bạn nên xác định cả hai lớp nhưng ban đầu cố gắng deserialize làm phiên bản hiện tại. Trong khối catch của bạn, deserialize nó như là phiên bản di sản, sau đó nâng cấp nó lên hiện tại và lưu nó trở lại. Khi không có phiên bản cũ nào tồn tại, bạn có thể xóa mã.

0

Sau khi điều tra một vài lựa chọn, tôi đã thực hiện các kết luận sau:

Lý tưởng nhất là tôi sẽ có thể truy cập giá trị từ bản gốc NameValueCollection và tự chuyển nó sang Dictionary<string, string>. Cách duy nhất để thực hiện điều này là triển khai ISerializable, nhưng điều này đặt ra hai vấn đề chính: phù hợp với việc đặt tên dữ liệu kế thừa và đưa logic tuần tự hóa cho tất cả các lớp kế thừa (trong đó có hàng trăm lớp).

Có hiệu quả, điều này đặt tôi vào liên kết. May mắn thay, tôi đã có thể xác định rằng lĩnh vực này thực sự chỉ được sử dụng như là một bản tóm tắt các lỗi xác nhận biểu mẫu và không nên được serialized ở nơi đầu tiên, do đó tôi đã loại trừ nó từ serialization.

Các vấn đề liên quan