現在、私は非常にイライラする問題に直面しています。少し簡単にするために、問題を抽象化しようとします。カスタムオブジェクトをあるプロセスでデータベースにシリアライズし、別のプロセスでデシリアライズする必要があります。
2 つのアセンブリがあります。AppToDB.dllとAppFromDB.dll。私は 3 番目のアセンブリを持っています - MyCustomObject.dll- これらのアセンブリの両方に参照が含まれています。MyCustomObject.dll拡張しますMarshalByRefObject。
私AppToDB.dllは次のコードを実行します:
    public bool serializeToDB(MyCustomObject obj)
    {            
        OdbcDataAdapter da = new OdbcDataAdapter();
        MemoryStream memStream = new MemoryStream();
        try
        {
            ObjRef marshalledObj = RemotingServices.Marshal((System.MarshalByRefObject)obj);
            // Serialize the object; construct the desired formatter
            IFormatter oBFormatter = new BinaryFormatter();
            // Try to serialize the object
            oBFormatter.Serialize(memStream, marshalledObj);
            // Create byte array
            byte[] serialized = memStream.ToArray();
            // Build the query to write to the database
            string queryString = 
                     "INSERT INTO MyCustomObject(id, object) VALUES(?, ?)";
            OdbcCommand command = new OdbcCommand(queryString, connection);
            command.Parameters.AddWithValue("id", 1);
            command.Parameters.AddWithValue("object", serialized);
            // Write the object byte array to the database
            int num = command.ExecuteNonQuery();
     }
     catch { }
 }
私はAppFromDB.dllこのコードを実行します:
    public OCR.Batch deserializeFromDB()
    {            
        MemoryStream memStream = new MemoryStream();
        try
        {
            string queryString = "SELECT object FROM FCBatch";
            OdbcCommand command = new OdbcCommand(queryString, connection);
            OdbcDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess);
            // Size of the BLOB buffer.
            int bufferSize = 100;
            // The BLOB byte[] buffer to be filled by GetBytes.
            byte[] outByte = new byte[bufferSize];
            // The bytes returned from GetBytes.
            long retval;
            // The starting position in the BLOB output.
            long startIndex = 0;
            MemoryStream dbStream = new MemoryStream();
            while (reader.Read())
            {
                // Reset the starting byte for the new BLOB.
                startIndex = 0;
                // Read bytes into outByte[] and retain the number of bytes returned.
                retval = reader.GetBytes(0, startIndex, outByte, 0, bufferSize);
                // Continue while there are bytes beyond the size of the buffer.
                while (retval == bufferSize)
                {
                    dbStream.Write(outByte, 0, bufferSize);
                    dbStream.Flush();
                    // Reposition start index to end of last buffer and fill buffer.
                    startIndex += bufferSize;
                    retval = reader.GetBytes(0, startIndex, outByte, 0, bufferSize);
                }
                // Write the remaining buffer.
                dbStream.Write(outByte, 0, (int)retval);
                dbStream.Flush();
            }
            // Close the reader and the connection.
            reader.Close();
            dbStream.Position = 0;
            object temp = oBFormatter.Deserialize(dbStream);
            MyCustomObject obj = (MyCustomObject)temp;
            return null;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            return null;
        }
    }
OK、両方のコードでMemoryStreamオブジェクトを確認できます。最初AppToDBに作成され、その内容を見ると、707 バイトが含まれています。罰金。それをデータベースに書き込み、そこに BLOB として保存します。次にAppFromDB、BLOB を取得してbyte[]配列に格納します。byte[]配列をMemoryStream再度aに書き込むと、MemoryStreamオブジェクトに 707 バイトが含まれていることがわかります。これらはすべて、元のように配置されています。オブジェクトの転送に成功したようです。
問題は にありますobject temp = oBFormatter.Deserialize(dbStream);。逆シリアル化しようとするとすぐに、私objectは透過プロキシであり、キャストできませんMyCustomObject!! 元のオブジェクトを取り戻すにはどうすればよいですか? #@& の名前でどのように MemoryStream オブジェクトを持つことができますか....メモリ内...シリアル化する準備ができています...そして突然、再び透過プロキシになります。
私は途方に暮れています。助けていただければ幸いです。答えを持っている人のために #@& に祈ります ;)
編集 1 わかりました。(問題は解決しませんが) 物事が理にかなっていると言わざるを得ません。私の問題: 片側にオブジェクト (状態を含む) があり、それをデータベースに保存して、数日後に反対側の別のプロセスで使用できるようにする必要があります。
シリアライズ可能とマークされていないサードパーティのオブジェクトをラップしているため、私のオブジェクトはシリアライズ可能ではありません。したがって、私の唯一のオプションは、順番にシリアライズ可能な ObjRef を返すマーシャリングのようです。しかしもちろん、数日後、デシリアライズしているオブジェクトは単なる参照であり、元のオブジェクトは失われています。
問題を解決するにはどうすればよいですか? もっと多くの人がこれに遭遇したにちがいなく、私は答えを見つけることができないようです...
編集 2 OK、サード パーティ オブジェクトに同形の独自のシリアル化可能なクラスを作成するつもりだと思います。次に、サードパーティのオブジェクト全体を実行し、その状態情報などを保存/ラップします。次に、オブジェクトをデータベースにシリアル化します...私の唯一のオプションのようです。
編集3 しばらくしてからこの問題を再開します。Edit 2に投稿されたソリューションが機能しないことに気付きました。サード パーティのアセンブリが認識しているオブジェクトに逆シリアル化する必要があります。これは、サード パーティのアセンブリが操作を実行し続けるためです。