Passing OracleLob as parameter to a function

2019-07-29 15:43发布

问题:

I want to accomplish a similar thing:

try
{
    openConnection();
    OracleCommand cmd = new OracleCommand("SELECT CUSTOMER_ID, IMAGE_BLOB FROM CUSTOMER_IMAGE WHERE CUSTOMER_ID IN (3026)", conn);
    string pubID = "";
    OracleDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess);

    //create the report object
    MemoryStream memStream;
    DataSet ds = new DataSet();
    DataTable ImageTable = new DataTable();
    BinaryReader binReader;
    DataRow dr;

    byte[] byteArrName;
    OracleLob blob;

    while (reader.Read())
    {
        pubID = reader.GetValue(0).ToString();

        // Obtain a LOB
        blob = reader.GetOracleLob(1);

        // Create a byte array of the size of the Blob obtained
        byteArrName = new byte[blob.Length];

        // Read blob data into byte array
        int i = blob.Read(byteArrName, 0, System.Convert.ToInt32(blob.Length));

        //Copied the contents of byte array to stream
        memStream = new MemoryStream(byteArrName);

        //Create a column of type byte[]
        ImageTable.Columns.Add(new DataColumn("id", typeof(string)));
        ImageTable.Columns.Add(new DataColumn("image", typeof(System.Byte[])));

        //Reading the stream which has the blob data
        binReader = new BinaryReader(memStream);
        dr = ImageTable.NewRow();

        dr["id"] = pubID;
        //ReadBytes method to add a byte array of the image stream.
        dr["image"] = binReader.ReadBytes((int)binReader.BaseStream.Length);
        ImageTable.Rows.Add(dr);

        memStream.Close();
        binReader.Close();
    }

    ds.Tables.Add(ImageTable);

    //Creating a temporary dataset which hold the image
    ds.WriteXmlSchema(@Directory.GetCurrentDirectory() + "\\temp.xsd");

    reader.Close();
    conn.Close();
}

Now, I'll populate that temp.xsd in the Crystal Report such that the image will be displayed dynamically. This is just a sample code I wrote from scratch, but to fit my scenario, I need to get the image that is already in dtAcctSigner.Rows[0]["IMAGE_BLOB"], so just wondering if there's any way I can fetch this BLOB just like I fetch in the above code as

OracleDataReader.GetOracleLob();

For that, I need to pass a column of the datatable(Type-OracleLob) as a parameter to a function like this:

Update(dtAcctSigner.Rows[0]["IMAGE_BLOB"]);

And the function goes as follows:

public void Update(OracleLob a)
{ 
// I want to do take the OracleLob and make into a memorystream and put it into temp.xsd here
}

But I get an error:

cannot convert 'object' to 'OracleLob'

Please let me know what I'm doing wrong.

回答1:

using(reader)
{
      //Obtain the first row of data.
      reader.Read();
      //Obtain the LOBs (all 3 varieties).
      OracleLob BLOB = reader.GetOracleLob(1);
      ...

      //Example - Reading binary data (in chunks).
      byte[] buffer = new byte[4096];
      while((actual = BLOB.Read(buffer, 0, buffer.Length)) >0)
         Console.WriteLine(BLOB.LobType + 
            ".Read(" + buffer + ", " + buffer.Length + ") => " + actual);

      ...
}

I personally would create and add columns to the DataTable this way but it's up to you to try it this way or another way that you know will work

DataTable table = new DataTable("ImageTable"); //Create a new DataTable instance.

DataColumn column0 = new DataColumn("id"); //Create the column.
column.DataType = System.Type.GetType("System.String"); //Type string 

DataColumn column1 = new DataColumn("image"); //Create the column.
column.DataType = System.Type.GetType("System.Byte[]"); //Type byte[] to store image bytes.
column.AllowDBNull = true;
column.Caption = "My Image";

table.Columns.Add(column0); //Add the column to the table.
table.Columns.Add(column1); //Add the column to the table.

Then, add a new row to this table and set the value of the MyImage column.

DataRow row = table.NewRow();
row["MyImage"] = <Image byte array>;
tables.Rows.Add(row);