问题
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);
来源:https://stackoverflow.com/questions/12149618/passing-oraclelob-as-parameter-to-a-function