04 September 2015

Find Distinct Objects from List of Objects using LINQ

To find distinct values from list of values in C# is a one line task by using LINQ's Distinct() method. This works well with primitive types but if you run the same method on List of custom Objects you will not get distinct objects based on its properties. To achieve this you an option to implement IEqualityComparer interface and use it to find distinct objects based on its properties. In the implementation of  Equals method you can define which properties to check for equality.

Below code provides the complete solution to get distinct objects from list of objects.


 
 using System.Collections.Generic;
    public class Team
    {
        public string Name {get;set;}
        public int Score {get;set;}
    }
        //Create some dummy data with duplicates
        public List<Team> lstTeam = new List<Team>{
        new Team{Name="Brazil", Score=1},
        new Team{Name="Man U", Score=1},
        new Team{Name="Man U", Score=1},
        new Team{Name="Brazil", Score=2},
        new Team{Name="Man U", Score=2},
        new Team{Name="Brazil", Score=2}

        };   

    //This is where we use equality comparer implementation to find unique records
     List<Team> lstDistictTeams = lstTeam.Distinct<Team>(new DistinctComparer()).ToList();

     foreach(Team t in lstDistictTeams) // Output Distinct Objects
     {
         Console.WriteLine("Team {0} has Score {1}",t.Name,t.Score);
     }

    //This class provides a way to compare two objects are equal or not
     public class DistinctComparer : IEqualityComparer<Team>
        {
            public bool Equals(Team x, Team y)
            {
                return (x.Name == y.Name && x.Score == y.Score); // Here you compare properties for equality
            }
            public int GetHashCode(Team obj)
            {
                return (obj.Name.GetHashCode() + obj.score.GetHashCode());
            }
        } 

14 May 2015

Copy Data between two different MSSQL Databases on different servers using C#

You can copy data from one SQL table to another using INSERT command with SELECT within same database or databases on same server but things gets little complicated when databases are on two different server. Here is a C# snipplet you can use to copy data between two desperate databases on two different servers. Code is self explanatory with comments.  Your source and destination table fields needs to match.


// Create source connection
SqlConnection source = new SqlConnection(ConfigurationManager.ConnectionStrings["SourceConnectionString"].ConnectionString);
// Create destination connection
SqlConnection destination = new SqlConnection(ConfigurationManager.ConnectionStrings["DestinationConnectionString"].ConnectionString);


// Open source and destination connections.
source.Open();
destination.Open();

// Select data from Products table
SqlCommand cmd = new SqlCommand(@"SELECT customer
         ,name
         ,address1
         ,address2
         ,address3
         ,address4
         ,address6
         ,address5
         ,fax
         ,territory
         ,region
         ,class
        FROM
        [dbo].[slcustm]", source);
// Execute reader
Console.WriteLine("Read data  from [dbo].[slcustm] table");
SqlDataReader reader = cmd.ExecuteReader();

Console.WriteLine("Write data  to DestinationCustomers table");
// Create SqlBulkCopy

SqlBulkCopy bulkData = new SqlBulkCopy(destination);
//If you are copying larger amount of data don't forget to set the timeout flag. Default value is 30 seconds. 0 = No limit
bulkData.BulkCopyTimeout = 0;

// Set destination table name
bulkData.DestinationTableName = "DestinationCustomers";
// Write data
bulkData.WriteToServer(reader);
// Close objects
bulkData.Close();
destination.Close();

03 May 2015

ASP.NET Gridview with Filter in Header using Reflection and LINQ

Introduction

ASP.NET gridview by default provides facility for sorting and paging but no inbuilt facility to filter column. This article looks at possible way to implement filtering function within the Gridview.

Background

I came across this requirement of having a gridview which allows filtering data from within the gridview. I also wanted to preserve the sorting and paging of the gridview.
Rather than creating separate panel above gridview for each of the fields to filter data, wouldn't it be nice to put a textbox along with each header column to filter data.
This leads me to this solution I derived for it. This may not be the best solution to do it but it definitely works. Our goal is to achieve this.

You can download full source code from : ASP.NET Gridview with Filter in Header Source Code


How It All Works ?

Create ASP.NET Web Application project in Visual Studio. First of all, we will create a DTO class to hold some data that we can display in a gridview. For this demo, I have created a DTO class of outstanding orders that contains some properties and some dummy data.

[Serializable]
public class Outstanding
{
 public string Item { get; set; }
 public string Order { get; set; }
 public int Line { get; set; }
 public int Status { get; set; }
 public string ToLocation { get; set; }
 public decimal Qty { get; set; }
 public DateTime RegDate { get; set; }
 public string Location { get; set; }
 public decimal AllocQty { get; set; }

 public List GetOutstanding()
 {
  List lstOrders = new List();

  lstOrders.Add(new Outstanding() { Item = "CocaCola", 
  Order = "000101", Line = 1, Status = 20, 
  ToLocation = "Sydney", 
  Qty = 2000, RegDate = new DateTime(2014, 1, 1), 
  Location = "USA", AllocQty = 100 });
  lstOrders.Add(new Outstanding() { Item = "BubbleGum", 
  Order = "000101", Line = 1, Status = 20, 
  ToLocation = "Sydney", 
  Qty = 2500, RegDate = new DateTime(2014, 1, 11), 
  Location = "USA", AllocQty = 300 });
  lstOrders.Add(new Outstanding() { Item = "Coffee", 
  Order = "000111", Line = 1, Status = 50, 
  ToLocation = "Melbourne", 
  Qty = 2500, RegDate = new DateTime(2014, 1, 10), 
  Location = "USA", AllocQty = 100 });
  lstOrders.Add(new Outstanding() { Item = "Sugar", 
  Order = "000112", Line = 1, Status = 50, 
  ToLocation = "Melbourne", 
  Qty = 2300, RegDate = new DateTime(2014, 1, 10), 
  Location = "NZ", AllocQty = 300 });
  lstOrders.Add(new Outstanding() { Item = "Milk", 
  Order = "000112", Line = 1, Status = 50, 
  ToLocation = "Melbourne", 
  Qty = 2300, RegDate = new DateTime(2014, 1, 10), 
  Location = "NZ", AllocQty = 200 });
  lstOrders.Add(new Outstanding() { Item = "Green Tea", 
  Order = "000112", Line = 1, Status = 20, 
  ToLocation = "Melbourne", 
  Qty = 300, RegDate = new DateTime(2014, 1, 10), 
  Location = "NZ", AllocQty = 220 });
  lstOrders.Add(new Outstanding() { Item = "Biscuit", 
  Order = "000131", Line = 1, Status = 70, 
  ToLocation = "Perth", 
  Qty = 200, RegDate = new DateTime(2014, 1, 12), 
  Location = "IND", AllocQty = 10 });
  lstOrders.Add(new Outstanding() { Item = "Wrap", 
  Order = "000131", Line = 1, Status = 20, 
  ToLocation = "Perth", 
  Qty = 2100, RegDate = new DateTime(2014, 1, 12), 
  Location = "IND", AllocQty = 110 });

  return lstOrders;
 }
}
Now in the Default.aspx page, add a gridview. To preserve sorting, add link button in HeaderTemplate with CommandName as "Sort" and CommandArgument as name of the column. Also, for the purpose of filtering the application will bind all the textboxes to single event (OnTextChanged="txtItem_TextChanged" ) and within the event we will determine which textbox fired it and take action accordingly.  So columns of the gridview will look like this. I have used different filters like =,>,<,>=&<= for numeric data and "contains" filter for string values.
Note : Make sure you name all your textboxes as txtFieldName so when filtering we can remove the txt from the ID of the textbox and then use reflection and LINQ to filter the data.
<asp:TemplateField SortExpression="Item">
    <HeaderTemplate>
      <asp:LinkButton ID="lbItem" runat="server" Text="Item" 
      CommandName="Sort" CommandArgument="Item"></asp:LinkButton>
      <br />
      <asp:TextBox runat="server" ID="txtItem" AutoPostBack="true" 
      OnTextChanged="txtItem_TextChanged"></asp:TextBox>
    </HeaderTemplate>
    <ItemTemplate>
       <%#Eval("Item") %>
    </ItemTemplate>
    </asp:TemplateField><asp:TemplateField SortExpression="Line" 
    ItemStyle-HorizontalAlign="Right" HeaderStyle-HorizontalAlign="Right">
     <HeaderTemplate>
        <asp:LinkButton ID="lbLine" runat="server" Text="Line" 
        CommandName="Sort" CommandArgument="Line"
        CssClass="RightAlign"></asp:LinkButton>
      <br />
     <table>
      <tr>
       <td>
        <asp:DropDownList runat="server" 
        ID="ddlFilterTypeLine" CssClass="upperCaseText">
        <asp:ListItem Text="=" Value="=" 
        Selected="True"></asp:ListItem>
        <asp:ListItem Text=">" Value=">"></asp:ListItem>
         <asp:ListItem Text=">=" Value=">="></asp:ListItem>
         <asp:ListItem Text="<" Value="<"></asp:ListItem>
        <asp:ListItem Text="<="  Value="<="></asp:ListItem>
         </asp:DropDownList>
      </td>
     <td>
     <asp:TextBox runat="server" ID="txtLine" Width="50" 
     AutoPostBack="true" OnTextChanged="txtItem_TextChanged" 
     CssClass="upperCaseText"></asp:TextBox>
    </td>
</tr>
</table></HeaderTemplate>
<ItemTemplate>
<%#Eval("Line","{0:0}")%>
</ItemTemplate>
</asp:TemplateField> 
Now in the Page_Load event, we will bind gridview to the dummy data. I have kept data in ViewState for this demo.
if (!Page.IsPostBack)
{
 Outstanding objOutstanding = new Outstanding();

 List lstOutstandingOrders = new List();
 lstOutstandingOrders = objOutstanding.GetOutstanding();

 ViewState["columnNameO"] = "RegDate";
 grdViewOutstanding.DataSource = lstOutstandingOrders;
 grdViewOutstanding.DataBind();

 ViewState["lstOutstandingOrders"] = lstOutstandingOrders;
 upnlOutstanding.Update();
}  
In the textbox's text change event, we will find out which textbox fired it by looking at the ID of a sender and take action accordingly. Finally, we will bind the data to gridview. To preserve the values in filter after postback, I created a seperate method which gets called everytime postback occurs and set values in corresponding textboxes and filters after postback.

In here what happens is all the textboxes are bound to single event so when even is fired you will first find out which textbox has fired that event and remove txt from the ID of textbox to get the name of the property to filter. x.GetType().GetProperty(filterName).GetValue(x, new object[] { } ) provides the value of associated property from list of objects. This is using reflection to get the property of Outstanding class based on input "filterName" as string value and then get the value of the property from the object and compare it to what is passed in the textbox.

 
        // For Outstanding Orders - Single Event bound  to all textboxes
        protected void txtItem_TextChanged(object sender, EventArgs e)
        {
            if (ViewState["lstOutstandingOrders"] != null)
            {
                List allOutstanding = (List)ViewState["lstOutstandingOrders"];
                TextBox txtBox = (TextBox)sender;
                string filterName = txtBox.ID.Substring(3); // remove txt from Textbox ID. You need to make sure that all the textboxes for filtering are named as txtFieldName
                //Check if there is a dropdown associated with current filter.
                if (grdViewOutstanding.HeaderRow.FindControl("ddlFilterType" + filterName) != null)
                {
                    //Get value from filter type dropdown
                    string filtrerType = ((DropDownList)grdViewOutstanding.HeaderRow.FindControl("ddlFilterType" + filterName)).SelectedItem.Value;

                    //Special case for DateTime
                    if (filterName == "RegDate")
                    {
                        DateTime filterValue = DateTime.Parse(txtBox.Text.Trim());
                        //Use LINQ reflection to find value for the input filer value
                        //x.GetType().GetProperty(filterName).GetValue(x, new object[] { })-- This is the LINQ reflection to get value 
                        //x.GetType().GetProperty(filterName) -- This gives you the actual property associated with Outstanding class based on input property name as string value. 
                        //Then we call get value to get its acutal value and compare it with what is being passed into textbox
                        if (filtrerType == "=")
                            allOutstanding = allOutstanding.Where(x => DateTime.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) == filterValue).ToList();
                        else if (filtrerType == ">")
                            allOutstanding = allOutstanding.Where(x => DateTime.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) > filterValue).ToList();
                        else if (filtrerType == ">=")
                            allOutstanding = allOutstanding.Where(x => DateTime.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) >= filterValue).ToList();
                        else if (filtrerType == "<")
                            allOutstanding = allOutstanding.Where(x => DateTime.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) < filterValue).ToList();
                        else if (filtrerType == "<=")
                            allOutstanding = allOutstanding.Where(x => DateTime.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) <= filterValue).ToList();
                    }
                    else // Parse Numbers as decimal
                    {
                        if (filtrerType == "=")
                            allOutstanding = allOutstanding.Where(x => decimal.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) == decimal.Parse(txtBox.Text.Trim())).ToList();
                        else if (filtrerType == ">")
                            allOutstanding = allOutstanding.Where(x => decimal.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) > decimal.Parse(txtBox.Text.Trim())).ToList();
                        else if (filtrerType == ">=")
                            allOutstanding = allOutstanding.Where(x => decimal.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) >= decimal.Parse(txtBox.Text.Trim())).ToList();
                        else if (filtrerType == "<")
                            allOutstanding = allOutstanding.Where(x => decimal.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) < decimal.Parse(txtBox.Text.Trim())).ToList();
                        else if (filtrerType == "<=")
                            allOutstanding = allOutstanding.Where(x => decimal.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) <= decimal.Parse(txtBox.Text.Trim())).ToList();
                    }
                    //Hold Filter Type in ViewState to preserve what is selected for use during postback
                    ViewState["OFilter" + filterName] = filtrerType;
                }
                else // Only string value
                {
                    allOutstanding = allOutstanding.Where(x => x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString().ToUpper().Contains(txtBox.Text.Trim().ToUpper())).ToList();
                }

                //Hold the filter value in ViewState. This will be used in ResetFilterAndValueOutstanidn() during postback
                ViewState["O" + filterName] = txtBox.Text.Trim().ToUpper();

                ViewState["lstOutstandingOrders"] = allOutstanding;
                grdViewOutstanding.DataSource = allOutstanding;
                grdViewOutstanding.DataBind();

                ResetFilterAndValueOutstanding();

            }


        } 
ResetFilterAndValueOutstanding() method restores values in filter textbox and filter type in dropdown after each postback. All the filter values and filter types are stored in ViewState with key value starting with "O". Make sure you don't store any other data in ViewState with key value starting with "O" because when removing the filter we will remove all the ViewState values starting with "O".
        protected void ResetFilterAndValueOutstanding()
        {
            //All the filters and filtervalues are stored in ViewState staring with "O"
            foreach (var k in ViewState.Keys)
            {
                if (k.ToString().StartsWith("O"))
                {
                    //Check if there is a textbox in GridView Header for this ViewState value. 
                    if (grdViewOutstanding.HeaderRow.FindControl("txt" + k.ToString().Substring(1)) != null)
                    {
                        ((TextBox)grdViewOutstanding.HeaderRow.FindControl("txt" + k.ToString().Substring(1))).Text = ViewState[k.ToString()].ToString().ToUpper();
                    }
                    //Check if there is a dropdownlist in GridView for this ViewState value.
                    if (grdViewOutstanding.HeaderRow.FindControl("ddlFilterType" + k.ToString().Substring(1)) != null)
                    {
                        foreach (ListItem li in ((DropDownList)grdViewOutstanding.HeaderRow.FindControl("ddlFilterType" + k.ToString().Substring(1))).Items)
                        {
                            if (li.Text == ViewState["OFilter" + k.ToString().Substring(1)].ToString()) li.Selected = true; else li.Selected = false;
                        }
                    }
                }
            }
          
        }
Add a link button on top of the gridview called "Remove Filter" which will remove all the ViewState with keys starting with "O" and rebind gridview to data and reset all filters to its original values.
protected void lbRemoveFilterOutstanding_Click(object sender, EventArgs e)
        {
            //Find all the ViewState Keys starting with "O". This represents Filters and Filter Values
            List lstKeysToRemove = new List();
            foreach (var k in ViewState.Keys)
            {
                if (k.ToString().StartsWith("O"))
                {
                    lstKeysToRemove.Add(k.ToString());
                }
            }
            foreach (string key in lstKeysToRemove)
            {
                ViewState.Remove(key);
            }
         
            Outstanding objOutstanding = new Outstanding();
            List lstOutstandingOrders = new List();
            lstOutstandingOrders = objOutstanding.GetOutstanding();
          
            grdViewOutstanding.DataSource = lstOutstandingOrders;
            grdViewOutstanding.DataBind();

            ViewState["lstOutstandingOrders"] = lstOutstandingOrders;
        }
There is paging and sorting enabled on the gridview which is easy to understand. This is one of the way to implement filtering on a gridview with paging and sorting.

Happy Coding !!!

15 September 2010

File Not Found Exception in Application_Error of Global.asax

I got this nasty error of "File Not Found." in Application_Error of Global.asax file on every web page request of my web application in ASP.NET. I try to check what is causing this File Not Found exception on every single request. Initially I try to catch the exception and check what is stack trace is saying but that is of not much help as there wasn't any indication what is causing it. Then I found the solution. Here it is for those who are trying to resolve it. Save some of your productive hours.

Step 1 : Set break point at Application_Error of Global.asax .

Step 2 : Start debugging your application and when the request hit the Application_Error break point type

 ((HttpApplication)sender).Context.Request.Url  

into Watch window of visual studio.

This will give you the information on which resource is missing and why this specific exception is generated on every single request.

Happy Coding !!!

23 May 2010

Show Session Timeout countdown on ASP.NET page

Hi,

I came across a really nice feature that you can use in ASP.NET to show session timeout to users. This provides rich user experience. I used javascript to create this facility. Hope this will help someone looking for the solution.

 var timeout = '<%= Session.Timeout * 60 * 1000 %>';  
 var timer = setInterval(function() { timeout -= 1000; document.getElementById('countDown').innerHTML = time(timeout); if (timeout == 0) { clearInterval(timer); alert('Your session has expired!') } }, 1000);  
 function two(x) { return ((x > 9) ? "" : "0") + x }  
 function time(ms) {  
 var t = '';  
 var sec = Math.floor(ms / 1000);  
 ms = ms % 1000  
 var min = Math.floor(sec / 60);  
 sec = sec % 60;  
 t = two(sec);  
 var hr = Math.floor(min / 60);  
 min = min % 60;  
 t = hr+":"+two(min) + ":" + t;  
 return "You session will timeout in " + t ;  
 }  


add a span named countDown to the page where you want to display this session timeout message. If you want it to display on all the pages once user is logged in then put it in Master page and voila !!! Your session timeout message will be there to warn user.

 <span id="countDown">  
  </span>  

14 April 2010

Creating Custom Membership Provider for Login Control in ASP.NET

You may have came across the situation where you want to use .NET's membership provider facility but don't want to use tables and stored procedures generated by aspnet_regsql.exe . You want to use your own simple Users table in your own database with just few fields like UserID, Password and Role. It may seems like a big task to create your own Membership Provider to use your own login logic but it is not that hard. Just follow the steps below :

1 > Create your own Membership Provider Class and inherit it from base MembershipProvider class. If you are using VB.NET the needed methods are added automatically. If you are using C# just right click the MembershipProvider class and add the properties and methods . Don't forget to import System.Configuration.Provider namespace.

The IDE will generate all the methods and properties and you don't have to implement all of them.

The only method that you need to implement is ValidateUser(string username, string password)

You can leave all the other methods throw an exception unless you explicitly want the facility provided by non implemented method.


public class MyCustomMemershipProvider : MembershipProvider  
 {  
 public int TryLogin(string id, string pass) // My own login method  
 {  
 int roleId = 0;  
 DatabaseUtilityHelper databaseHelper = new DatabaseUtilityHelper();  
 SqlConnection con = databaseHelper.GetBBCDatabaseConnection();  
 SqlParameter[] agentParams = new SqlParameter[] {  
 new SqlParameter("@UserId",id),  
 new SqlParameter("@Password",pass)};  
 con.Open();  
 SqlDataReader reader = DatabaseUtility.ExecuteReader(con, "login_user", CommandType.StoredProcedure, agentParams);  
 if (reader.Read())  
 {  
 roleId = Int32.Parse(reader.GetSqlValue(1).ToString());  
 }  
 else  
 {  
 roleId = 0;  
 }  
 con.Close();  
 return roleId;  
 }  
 public override string ApplicationName  
 {  
 get  
 {  
 throw new NotImplementedException();  
 }  
 set  
 {  
 throw new NotImplementedException();  
 }  
 }  
 .....  
 ..... // Generated Code  
 ....  
 ....  
 public override bool ValidateUser(string username, string password)  
 {  
 int result = TryLogin(username, password);  
 if (result > 0)  
 {  
 return true;  
 }  
 else  
 {  
 return false;  
 }  
 } 


2 > Add CustomeMemberShip Provider to your web.config




 <membership defaultProvider="MyCustomMemershipProvider">  
 <providers>  
 <clear/>  
 <add  
 name="MyCustomMemershipProvider"  
 type="BBCApplication.BusinessLogic.MyCustomMemershipProvider"/>  
 </providers>  
 </membership>  


3.> Add Membership Provider for your login control on Login.aspx page.

In the Properties window of the Login control set MembershipProvider to your MyCustomeMembershipProvider class.

That is it.
Off you go to your own login logic with custom membership provider.

20 November 2009

Set NTFS folder permissions on remote machine using .NET and WMI

After considerable amount of efforts and trial I was finally able to hack the solution to set NTFS permissions on a remote machine using .NET. For local file system it is just couple of line of codes and it works like a charm but when it comes to remote machines it just gives you a nightmare . So here goes my solution. I am sure this will help someone.

public bool SetPermissions(string remoteDir, string MachineName, string UserName, string Password) // Username and Password is of Admin account on remote machine
{
string TempName = remoteDir;
int Index = TempName.IndexOf(":");
string DriveLetter = ConfigurationManager.AppSettings["ShareDriveLetter"]; // e.q. C
if (Index != -1)
{
string[] arr = TempName.Split(new char[] { ':' });
DriveLetter = arr[0];
TempName = TempName.Substring(Index + 2);
}

ManagementPath myPath = new ManagementPath();
myPath.NamespacePath = @"root\CIMV2";

ConnectionOptions oConn = new ConnectionOptions();
oConn.Username = UserName;
oConn.Password = Password;
oConn.EnablePrivileges = true;
myPath.Server = MachineName;

ManagementScope scope = new ManagementScope(myPath, oConn);
scope.Connect();
//without next strange manipulation, the os.Get().Count will throw the "Invalid query" exception
remoteDir = remoteDir.Replace("\\", "\\\\");
ObjectQuery oq = new ObjectQuery("select Name from Win32_Directory where Name = '" + remoteDir + "'");
using (ManagementObjectSearcher os = new ManagementObjectSearcher(scope, oq))
{
if (os.Get().Count == 0) //It don't exist, so create it!
{
ManagementPath path2 = new ManagementPath();
path2.Server = MachineName;
path2.ClassName = "Win32_Process";
path2.NamespacePath = @"root\CIMV2";
ManagementScope scopeProcess = new ManagementScope(path2, oConn);

using (ManagementClass process = new ManagementClass(scopeProcess, path2, null))
{
//Command line that you want to execute on remote machine
string commandLine = @"cmd /C cacls " + TempName +" /C /T /E /P "+"0909020:F"; // 0909020:F is username:permissions

using (ManagementBaseObject inParams = process.GetMethodParameters("Create"))
{
inParams["CommandLine"] = commandLine;
inParams["CurrentDirectory"] = DriveLetter + @":\\";
inParams["ProcessStartupInformation"] = null;
using (ManagementBaseObject outParams = process.InvokeMethod("Create", inParams, null))
{
int retVal = Convert.ToInt32(outParams.Properties["ReturnValue"].Value);

return (retVal == 0);
}
}
}



}
else
{
return true;//if exists, return true; you may want to return false, of course
}
}
return false;
}