Entity Framework and appending VARBINARY field - c#

i am trying to add bytes of a file to a field in the database which is of type VARBINARY bu this needs to be appended due to file size constraits
Is there any example code/website of how to do this? Or is it even possible to append the bytes to this field using Entity Framework?
I need to append the data as getting a byte array of 1GB + is going to cause memory exceptions so I think this is the only way..
Some code I have done
using (var stream = File.OpenRead(fn))
{
long bytesToRead = 1;
byte[] buffer = new byte[bytesToRead];
while (stream.Read(buffer, 0, buffer.Length) > 0)
{
Item = buffer;
}
}
Thanks for any help

The basic idea is making an stored procedure that implements an update like this:
UPDATE MyTable SET Col = Col + #newdata WHERE Id = #Id
and invoking it using ExecuteSqlCommand (see MSDN docs here).
But in this case you're only transfering the problem to the SQL Server side The column must be retrieved, modified, and written back).
To really get rid of the memory problem, implement your stored procedure using UPDATETEXT, which is much more efficient for your requirements:
Updates an existing text, ntext, or image field. Use UPDATETEXT to change only a part of a text, ntext, or image column in place. Use WRITETEXT to update and replace a whole text, ntext, or image field

When storing large files in a database, it is usual to store the file on disc on the Web Server rather than in the database. In the database you store the path to the file, thus your code can get to it's contents without having to store gigs of data in the database.
However, if you are attempting to manipulate the contents of a 1GB+ file in memory, this is going to be interesting however you do it...

Related

Saving reference to a blob type

I want to save a reference to an image that will be stored in the database.
But I am not sure how to approach this in C# (Entityframework).
Using EF's code first approach.
In the Model class, must i do String imageReference, og must I use byte? Or is there another and better solution to this? What I want once the database is created, for that column, it should say Blob or what ever is used to hold large objects like images.
I am also thinking that only saving a reference in the database, instead of the image itself might be a solution. But I don't know which is better?
You need to create it as a byte, and your db should be blob
var image = new ImageEntity(){
imageReference= convertImageToByteArray(image)
}
_Context.Images.Add(image);
_Context.SaveChanges();
Convert ur image to a byte array:
public byte[] convertImageToByteArray(Image imageIn)
{
MemoryStream memStream = new MemoryStream();
imageIn.Save(memStream , ImageFormat.Gif); //u may choose other formats
return memStream .ToArray();
}
I would recommend saving the file path as reference instead of storing it as a blob unless you have no choice. This is because a larger DB will degrade the performance, the hard disk would do a better job at handling files. If your image files are larger than 1MB, the file system has an advantage over a SQL Server. Also storing it in the file system has greater flexibility (i.e. you may migrate your files elsewhere next time, and change the link in the DB during migration, you can't do that on the DB)

Retrieve and Place Image From SQL Db to a PictureBox In C# WinFormApp

I want to save and retrieve an image from database and place it in a picturebox in my windows form application.
Does any one have any code for it? and please tell me the data type in SQL that I have to use for storing my image (which one is better, Varbinary(MAX) or Image?)
this is the code i'm using for taking the image from a PicturBox and making it into a binary and storing it into a Varbinary(MAX) in the Database and when I Run The code It says: Implicit conversion from data type varchar to varbinary(max) is not allowed. Use the CONVERT function to run this query.
System.IO.MemoryStream mymemory = new System.IO.MemoryStream();
img.Save(mymemory,Pbox.Image.RawFormat);
Byte[] myarray = mymemory.GetBuffer();
What should I do?
If anyone has better code please help me with copying the code here for me
any help will be appreciated.
Based on your prior "connection strings" question, the best answer would be to not save the image in that table, only a reference to it; either by using a filestream table or by a text field containing the file system location.

Right way to store Image in database through Entity Framework

I have converted an image to a byte array using below code to store it in Database
if (Request.Content.IsMimeMultipartContent())
{
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
foreach (var file in provider.Contents)
{
var filename = file.Headers.ContentDisposition.FileName.Trim('\"');
var attachmentData = new AttachmentData ();
attachmentData.File = file.ReadAsByteArrayAsync().Result;
db.AttachmentData.Add(attachmentData);
db.SaveChanges();
return Ok(attachmentData);
}
}
Here File column in DB is of type "varbinary(max)" and in EF model it is byte array (byte[]).
Using above code I was able to save the image in the File column something similar to "0x30783839353034453437304430413143136303832....." (This length is exceeding 43679 characters which is more than default given to any column so the data got truncated while storing it)
I have to change the default length(43679) of column to store it in database.
Am I doing it the correct way to retrieve and store image in Database. I was also thinking to store the image as "Base64 String" but 43679 will still exceed.
I am using Angular JS to show the image on front end which uses WebAPI to fetch and save the image as ByteArray in database.
Yes, It really helps to not know how databases work.
First:
varbinary(max)
This stores up to 2gb, not 43679 bytes.
Then:
similar to "0x30783839353034453437304430413143136303832.....
This is not how it is stored. This is a textual representation in uotput.
(This length is exceeding 43679 characters which is more than default given to
any column so the data got truncated while storing it)
There is no default given to any column - outside basically SQL Server Management Studio which likely will not be able to handle images as images and has a lot of limitations. But this is not the database, it is an admin ui.
I was also thinking to store the image as "Base64 String" but 43679 will still
exceed.
Actually no, it will exceed this by more - your data will be significantly longer as Base64 is longer than binary data.

Dapper and Varbinary(max) stream parameters

I'm trying to store a binary blob in a database table and get an output back from it. The data is stored in a MemoryStream object. I'm trying to save this to a sql server 2012 table using query async. The call succeeds but no data is inserted into the column. (e.g. I get a 0x0 entry when I query it back).
Sure enough, actually checking a trace I see dapper sending a 0x0. The memorystream has a length so am I doing something wrong or does dapper not support this scenario?
My query string is just a simple insert and gets the id and insertion time back.
I'm using the following call
using(var conn=new SqlConnection(_connstr)){
var dynParams = new DynamicParameters();
dynParams.Add("BinaryBlob",
_memoryStream,DbType.Binary,ParameterDirection.Input,-1);
var res = await conn.QueryAsync<MyResultType>(_queryStr, dynParams);
}
The query inserts a row and gets a timestamp back, but no data is actually inserted. What am I doing wrong?
Make sure you seek to the beginning of the Memory stream. Streams have a positional state. Another approach would be to convert the memory stream to a Byte[] before trying to persist it.
e.g.
_memorystream.Seek(0, SeekOrigin.Begin);

Retrieving image stored in long datatype

I have one web application, having one table in oracle10g having following structure:
Column Name DataType
UserImage long
My problem is that how should I display the IMAGE on my aspx page which is stored in long format?
If data type is BLOB or CLOB then it could be easier one, but it's stored in long.
I could not change the datatype since this is third party DB.
Please suggest me how could I achieve this. The solution could be either using Oracle or C#, I'm fine with both.
Thanks in advance.
You can't store an image in a 'long' datatype.
Instead - hold a static list of key-value pairs, each pair defines an index (say, from 1 to n) of an image
and the value holds the Image's file name.
For instance, the following pseudo code demonstrates a similar approach (should be implemented on the client/server side of your application, not in the DB
SWITCH (USERIMAGE)
CASE 1:
SETIMAGE("IMAGES/IMAGE_NUMBER_ONE.JPG");
BREAK:
CASE 2:
SETIMAGE("IMAGES/IMAGE_NUMBER_TWO.JPG");
BREAK:
and so on.
Another solution:
Assume your 1st table is called "Table1". create a new table in your database called my_images
Column name Column type Comments
UserImage LONG Foreign key to Table1.UserImage
ImageData BLOB
And,
SELECT t1.ImageData FROM Table1 t1, my_images mi
WHERE t1.UserImage == mi.UserImage;
The "chunk" characters you have posted seem to be a TIFF image. That gives an idea how the images are stored. In fact, the binary image data seems to be stored as character data. That's certainly completely unsupported and very fragile. I'd recommend converting it as soon as possible.
In the mean time, I can propose two ways of retrieving the data so I cannot guarantee that either one works.
But approaches are susceptible to characters sets: If two or more character sets are involved, your data will be converted and thereby destroyed. And both are susceptible to the maximum length of certain data types.
Approach 1:
Try to go via the RAW data type and retrieve it as a byte array. It's certainly limited to 32'000 characters, maybe even less.
SELECT UTL_RAW.CAST_TO_RAW(UserImage) FROM UNNAMED_TABLE WHERE ...
On the C# side, you should get an OracleBinary or byte[] instance.
Approach 2:
Try to retrieve it as a string. Then convert the string into a byte array using the original encoding (Encoding.GetBytes. With enough luck, the original data can be restored.

Categories

Resources