Friday, November 13, 2009

Using LINQ to query object hierarchies

I used LINQ to solve the following problem: find all titles of objects at hierarchy level X when you know object ID in hierarchy level Y. I cannot imagine if there is some other solution that is same short and clear as one that LINQ provides. Take a look and decide by yourself.
linq-levels-example Here is simple diagram with my entities. Here are my simple rules. Level1 has no parent level and my contain one ore more Level2 entities. Level2 entities have one Level1 parent and one or more Level3 enitities. Level3 entities have one Level2 parent entity and collection of one or more Items. So there is many-to-many relationship between Level3 and Items.
We cannot use composite pattern here because these classes will be very different and there will be no point where we need one common interface for them. That’s why we have one class per level. Also the number of levels is fixed and there is no plan to expand this hierarchy.
By the way, you can model arbitrary class hierarchies on this model and still use this example (as long as it doesn’t hurt performance and you are really sure what you are doing).
Excercise: having Level1 items collection and knowing Level3 item ID find all Items for specified Level3 item and return string of their titles separated by comma. As you don’t have access to source code of data source you must use IList<Level1> and LINQ.
We will use simple class structure given below and we expect that we already got list of Level1 items from some repository or data context.

public class Level1
{
    public int Id { get; set; }
    public string Title { get; set; }
    public IList<Level2> Level2Items { get; set; }
}

public class Level2
{
    public int Id { get; set; }
    public string Title { get; set; }
    public Level1 Parent { get; set; }
    public IList<Level3> Level3Items { get; set; }
}

public class Level3
{
    public int Id { get; set; }
    public string Title { get; set; }
    public Level2 Parent { get; set; }
    public IList<Item> Items { get; set; }
}

public class Item
{
    public int Id { get; set; }
    public string Title { get; set; }
}

Now it’s time to write some hardcore loops and create a cool code-hell… or maybe it’s time to be elegant and use LINQ as stated before. Using LINQ we can provide the following solution:

public string GetItemsStringForLevel3(IList<Level1> level1Items, int level3Id)
{           
    var items = from l in level1Items
                  from l2 in l.Level2Items
                  from l3 in l2.Level3Items
                  from p in l3.Items
                where l3.Id == level3Id
                select p.Title;

    return string.Join(", ", items.ToArray());
}

--
Happy Programming

jQuery for Absolute Beginners: The Complete Video Series

A great VIDEO series on all the nice effects (and functionality) you can achieve with jQuery JavaScript library for those who know NOTHING about it.
jQuery is a very powerful library. One of the first things I do when creating new project is to include the library in it. Microsoft is going to include it by default in ASP.NET web projects (All ASP.Net projects, not just MVC) starting Visual Studio 2010.
Here are some few examples of what you can do with it (VIDEO):

http://net.tutsplus.com/articles/web-roundups/jquery-for-absolute-beginners-video-series/?awesm=fbshare.me_EIez#



---
Happy Programming

Thursday, November 12, 2009

Statement cannot appear within a method body. End of method assumed

Today when I was developing web pages using asp.net,I encountered a problem as below:
Server Error in '/BC30289' Application.
 
Compilation Error Description:
An error occurred during the compilation of a resource required to service  this request. Please review the following specific error details and modify your  source code appropriately.

Compiler Error Message: 
BC30289:  Statement cannot appear within a method body. End of method assumed.

Error Line: Sub showImage(Byval id as string)
I replaced "<% %>" with
<script language="vbscript" runat="server"></script>

And then everything works fine.

That is because we cannot define asp 'sub' or 'function' between the body tag

--
Happy Programming

Use Output clause in Delete Statement in sqlserver 2005

Here i give simple example of delete statement with output clause.
if you want track the deleted row information at that time generally
we preffered trigger right?
here we inserte the deleted row in the other history table. we create
the two talbe one is data table and other for history purpose.
1) Create Table (Name:Table_1)
GO
CREATE TABLE [dbo].[Table_1]

( [id] [int] IDENTITY(1,1) NOT NULL,
[code] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,

CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED ( [id] ASC )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY]

2) Create Table For Save Deleted Record in other table (DeletedTblInfo)
GO
CREATE TABLE [dbo].[DeletedTblInfo]
( [DeletedTableInfoId] [int] IDENTITY(1,1) NOT NULL,

[DeletedTableId] [int] NULL,
[DeletedRowId] [int] NULL,
 [DeletedDateTime] [datetime] NULL,
CONSTRAINT [PK_DeletedTblInfo] PRIMARY KEY CLUSTERED ( [DeletedTableInfoId] ASC )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY]

3) insert data into data table
go
INSERT INTO Table_1
 (code)
VALUES
(‘test1′)

 go
INSERT INTO Table_1
 (code)
 VALUES
(‘test2′)
go

INSERT INTO Table_1
(code)
VALUES
(‘test3′)
go
INSERT INTO Table_1

(code)
VALUES
(‘test4′)
4) now delete from table 1 where id =4
–here the record save in the DeletedTblInfo
–DeletedTableId : the table id where data is deleted or the table name if you want then.
–DeletedRowId : deleted RowId

–DeletedDateTime : deleted DateTime
DELETE FROM Table_1
OUTPUT 1,DELETED.ID,getdate()
INTO DeletedTblInfo WHERE (Id = 4);

–now see the result in the history table
DeletedTableInfoId
DeletedTableId
DeletedRowId
DeletedDateTime
1
1
4
5/7/2008 12:53:52 PM

What is Maximum Request size for asp.net application?

The default max request size is 4MB (4096).
You can change a setting in your web.config to allow larger requests.
Here is the example:
   1: <configuration>
   2:        <system.web>

   3:            <httpRuntime  maxRequestLength="4096"/>
   4:        </system.web>

   5: </configuration>
This is default setting, we have to change this to the size that you want to allow user to request like 10MB, 20MB…

---
Happy Programming

Saturday, November 7, 2009

Multiple File Upload using JQuery

Introduction

In this article I have explained how to upload multiple files using file upload control. I have used jQuery plugin for uploading multiple files.

I have also explained how to check for file type, file maximum size limit using jQuery & also using server side validation code.
Download the Following Files



Namespace used

using System.Security.Cryptography;
using System.Text;
using System.IO;

Step 1: Include the jQuery Files needed on the page.

Assuming you have downloaded these files, create a reference to these files in the <head> section of your page as shown below:

<head id="Head1" runat="server">
<title>Multiple File Upload using JQuery</title>
<script src="Scripts/jquery-1.3.2.js"
type="text/javascript">
</script>
<script src="Scripts/jquery.MultiFile.js"
type="text/javascript">
</script>
</head>

Step 2: Add File Upload Control & Button on the Page.

<asp:FileUpload ID="FileUpload1" runat="server"
accept="gif|jpeg|bmp|png|jpg"
maxlength="5" />
<br />
<asp:Button ID="btnUpload" runat="server"
Text="Upload All" OnClick="btnUpload_Click" />
<br />
<asp:Label ID="lblMsg" runat="server" Text="">\
</asp:Label>
class=”multi” is used to specify that user can select multiple files.

maxlength property specify that user can upload maximum 5 files not more than that.

accept property used to restrict user to upload only certain type of file only.

Step 3: Double click on Upload Button & Write the code that is used to upload files.

protected void btnUpload_Click(object sender, EventArgs e)
{
if (ServerSideValidation() == true)
{
string SavePath, Msg = null;

// Get the HttpFileCollection
HttpFileCollection hfc = Request.Files;
for (int i = 0; i < hfc.Count; i++)
{
HttpPostedFile hpf = hfc[i];
if (hpf.ContentLength > 0)
{
SavePath = ConfigurationManager.AppSettings["PatientPhotoImages"].ToString()
+ GetUniqueKey() + GetFileExtension(hpf.FileName);
hpf.SaveAs(Server.MapPath(SavePath));
//SavePath can be saved in DB.
Msg += GetFileName(hpf.FileName.ToString()) + " , ";
}
}
lblMsg.Text = Msg + " Uploaded Successfully.";
}
}


Step 4: Write the private function which helps to Upload files.

This function helps to extract file extension from the fileName.

private string GetFileExtension(string FileName)
{
char saperator = ‘.’;
string[] temp = FileName.Split(saperator);

return "." + temp[1].ToString();
}

This function helps to get Unique Key, which is used to save files on server with different name that does not collied with each other.

private string GetUniqueKey()
{
int maxSize = 8;
char[] chars = new char[62];
string a;

a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";

chars = a.ToCharArray();

int size = maxSize;
byte[] data = new byte[1];

RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();

crypto.GetNonZeroBytes(data);
size = maxSize;
data = new byte[size];
crypto.GetNonZeroBytes(data);
StringBuilder result = new StringBuilder(size);

foreach (byte b in data)
{
result.Append(chars[b % (chars.Length - 1)]);
}

return result.ToString();
}

This function help to get Filename from the filepath.

private string GetFileName(string filePath)
{
FileInfo fi = new FileInfo(filePath);
return fi.Name;
}


Step 5: Add Server Side Validation Code

This is the function which is used to validate files that user wants to upload. If the client side validation does not work, this code will help us to identify the invalid files.

Validation rules like whether file type is correct or not, file size is valid or not.

If you do not want to validate the files on server side, you can ignore this code. But I prefer to use it.

private bool ServerSideValidation()
{
string errorMsg = string.Empty , temp=null;
bool errorFlag = true;

// Get the HttpFileCollection
HttpFileCollection hfc = Request.Files;
for (int i = 0; i < hfc.Count; i++)
{
HttpPostedFile hpf = hfc[i];
if (hpf.ContentLength > 0)
{
temp = ValidateImage(hpf);
if(temp != null)
{
errorMsg += GetFileName(hpf.FileName.ToString()) + " has error : " + temp;
temp = null;
}
}
}

if (errorMsg != "")
{
lblMsg.Text = errorMsg;
errorFlag = false;
}
return errorFlag;
}

This function used to check file type & file size. If file is invalid than it will return error message.

private string ValidateImage(HttpPostedFile myFile)
{
string msg = null;     
int FileMaxSize = Convert.ToInt32(ConfigurationManager.AppSettings["FileUploadSizeLimit"].ToString());
//Check Length of File is Valid or Not.
if (myFile.ContentLength > FileMaxSize)
{
msg = msg + "File Size is Too Large.";
}
//Check File Type is Valid or Not.     
if (!IsValidFile(myFile.FileName))
{                  
msg = msg + "Invalid File Type.";
}
return msg;
}

This function is used to check whether the file that user want to upload is valid file type or not.

private bool IsValidFile(string filePath)
{
bool isValid = false;

string[] fileExtensions = { ".bmp", ".jpg", ".png", ".gif", ".jpeg", ".BMP", ".JPG", ".PNG", ".GIF", ".JPEG" };

for (int i = 0; i < fileExtensions.Length; i++)
{
if (filePath.Contains(fileExtensions[i]))
{
isValid = true;
}
}
return isValid;
}

Conclusion:

This code is complete solution that helps to upload multiple file using File Upload with jQuery plugin. I was always in a need of such code in my route work so I decided to write the code that helps others also.

Hope this will help !!!

Thursday, October 29, 2009

EXISTS or COUNT(*) Which Do You Use To Check How Many Rows There Are?

Do you use this

IF (SELECT COUNT(*) FROM SomeTable
WHERE SomeColumn = SomeValue ) > 0

Or do you use this

IF EXISTS (SELECT * FROM SomeTable WHERE SomeColumn = SomeValue )

If you answered COUNT(*) then maybe you should take a look these two articles

Andrew Kelly has a nice post on SQLBlog
http://sqlblog.com/blogs/andrew_kelly/archive/2007/12/15/exists-vs-count-the-battle-never-ends.aspx

Matija Lah has a good post on his snaps & snippets blog
http://milambda.blogspot.com/2006/10/exists-or-not-exists-that-is-question.html