April 2007 - Posts
Last week I had a problem when I tried to export an image from the AGS 9.2 to a pdf file. I got this error: "Sys.WebForms.PageRequestManagerTimeoutException The server request timed out" from the Ajax Extension framework. Its occurred because the export operation was relatively long (something like 2 minutes) and the Ajax Extension Callback framework had a timeout.
How to solve this problem?
To solve this problem we can increase the timeout. You can change the timeout time by adding a new property to the script manager control. This property is called AsyncPostBackTimeOut and it can help us to define the number of seconds before the request will throw a request timeout exception*.
For example if you want that the timeout will take maximum 10 minutes your code should be look like this:
<asp:ScriptManager ID="ScriptManager1" runat="server"
AsyncPostBackTimeOut="600" >
</asp:ScriptManager>
* The default value of the AsyncPostBackTimeOut property is 90 seconds.
In our project we had a dilemma if we should store image files in database or in file system directory.
There are some pros' and cons' for each option, but the most important issue that influenced our decision was that we work with ESRI tools. If the image is small it's better to store it in the file system and not in the database. If we store the image in database (using SDE), it will takes some time and this operation couldn't be in real-time reaction (because the SDE will create a pyramids and others statistics operations before the image is being stored in the database).
I want to share with you an example to insert and retrieve images that have been stored in the database in Image type (SQL server data type, from BLOB family).
Insert an image to database:
private void InsertImageToDatabaseColumn(int imageId)
{
MemoryStream mem = new MemoryStream();
byte[] imageData = new byte[1024];
Stream imageStream = FileUpload1.PostedFile.InputStream;
int imageLength = FileUpload1.PostedFile.ContentLength;
string imageType = FileUpload1.PostedFile.ContentType;
int count = 0;
while (0 < (count = imageStream.Read(imageData, 0, imageData.Length)))
{
mem.Write(imageData, 0, count);
}
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ToString()))
{
using (SqlCommand command = new SqlCommand())
{
command.Connection = conn;
command.CommandText = "Insert into Images values (@Id,@Image)";
SqlParameter p1 = new SqlParameter();
p1.ParameterName = "Id";
p1.Value = imageId;
command.Parameters.Add(p1);
p1 = new SqlParameter();
p1.ParameterName = "Image";
p1.Value = mem.GetBuffer();
command.Parameters.Add(p1);
conn.Open();
command.ExecuteNonQuery();
}
}
}
Show an image from database:
private void GetAndBindImageCoulmn(int imageId)
{
byte[] imageBytes;
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ToString()))
{
using (SqlCommand command = new SqlCommand())
{
command.Connection = conn;
command.CommandText = "Select image from Images where id = @ImageId ";
SqlParameter parameter = new SqlParameter("ImageId", SqlDbType.Int);
parameter.Value = imageId;
command.Parameters.Add(parameter);
conn.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
reader.Read();
imageBytes = (byte[])reader.GetValue(0);
MemoryStream tempStream = new MemoryStream(imageBytes, 0, imageBytes.Length);
Bitmap bitmap = new Bitmap(tempStream);
Response.ContentType = "image/gif";
bitmap.Save(Response.OutputStream, ImageFormat.Gif);
Response.End();
}
}
}
}
There are three approaches to implement a primary key:
Natural key:
1. A column or collection of columns that define the table uniqueness (existing column\columns from data table).
Surrogate primary key: an auto-generated keys without any business relationship:
2. Auto-increment column (Aka sequence) that store in an ID column.
3. Auto-generated key using the Global Unique Identifier(GUID).
|
No. |
Subject |
Natural primary key |
Sequence key |
GUID key |
|
1 |
Extra data size(tables and indexes) |
Big index data |
Add 4 bytes for int and 8 for long (peer row) |
Add 16 bytes for each row |
|
2 |
Key visibility |
Seen and understood to users |
Hide from users |
Hide from users |
|
3 |
Modifying Keys |
Difficult to update |
Easy to modify |
Easy to modify |
|
4 |
Quantity of joins |
Reducing the join between tables(In some cases) |
When we use a link table that contain 2 keys from A, B table to C table we must include A, B ,C in any join. |
When we use a link table that contain 2 keys from A, B table to C table we must include A, B, C in any join. |
|
5 |
Sql statement complexity |
Hard to implement, must contain all the primary columns in almost any statement |
The easiest option to implement(Only one primary column, and it's contains only numeric incrementally number) |
More easy from the natural primary key, but slightly more difficult from the sequence key |
|
6 |
Ensuring uniqueness when working disconnected |
Very complicated |
The uniqueness can be broken if the identity key is duplicated(We can solve this problem if we use some tricks like: working with negative number for the primary key in the disconnected entities and changing the primary key when merging to master database) |
The best option, because the primary key can't be duplicated*.
* The chance to get the same key is 1/(2^127) |
|
8 |
Migrating data to other databases |
The synchronization is a little bit complicated |
Requires some work, especially in the synchronization process of the Foreign Key tables |
Just copy the data… |
Who is the winner?
It's a good question; I don't think that we have only one answer. It's depends on our requirements.
For example:
- If we using a data warehouse were we need to provide high performance read-only access, the problem of the key modification is less severed. In this case we should use the natural primary keys.
- If we are working with disconnected data and database synchronization, we should choose the GUID keys.
- If we have an application that doesn't work with disconnected data and have regular DML operations, we should choose the sequence keys.