Using Delegate Methods to “Broadcast” data to your Child Controls

 

I thought I’d make available an interesting piece of code that came about recently because I was using a Telerik Radstrip to display information that was all based on a single piece of data, in that case a Fiscal Year.  I decided to remove the Telerik aspect of this tutorial to make it available to a much broader audience but the theory remains.

In this scenario, we have a combobox that’s filled with all the OrderID from the database.  When we choose a specific order, we want all the related data displayed.  Now this is fairly straightforward but I thought I’d try and show how we did this using User Controls.  The goal, in this specific instance was to allow multiple programmers to work on maultiple parts of the project simultaneously, to that end, we broke up the project into modules and created user controls for each.  This was each programmer was responsible for his/her code and could checkin/out at their leisure with breaking the overall project.  However, this led us to need a way to handle the Events from the Parent control, which was then cascaded down to each Child control.

Why Delegate Methods?

Originally we were using Parent.Parent.Findcontrol.etc but I have to tell you, that got old pretty quickly, especially when alot of the Child Controls had multiple items (radgrids, dropdowns, etc.) that needed to know what Fiscal Year we were talking about.  After a few weeks of the design getting deeper and deeper into complexity, one of us broke off and built this method of broadcasting changes down to the Child Controls, rather than the Child Controls always trying to decipher if a change has occurred.

 

The layout

 

We built our Default.aspx page first and registered our (not yet existing) controls just so we could all have a base project to work in.

<%@ Register TagPrefix="ucHeader" TagName="HeaderControl" Src="~/userControls/headerControl.ascx" %>
<%@ Register TagPrefix="ucClients" TagName="ClientsControl" Src="~/userControls/clientsControl.ascx" %>
<%@ Register TagPrefix="ucProducts" TagName="ProductsControl" Src="~/userControls/productControl.ascx" %>

 

Then we created a generic layout which assembled the user controls.

Default.aspx

<table class="gridtable" style="width:100%;">
    <thead>
        <tr>
            <td colspan="2">
               <ucHeader:HeaderControl runat="server" ID="HeaderControl" />
            </td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td style="width:40%;vertical-align:top" >
                    <ucClients:ClientsControl runat="server" ID="ClientsControl" />               
            </td>
            <td style="width:60%;"  >
                    <ucProducts:ProductsControl runat="server" ID="ProductsControl" />               
            </td>
        </tr>
    </tbody>
</table>

That was pretty much it for that page.  At this point each of the programmers could start assembling their code with the knowledge that there eventually would be an object of type Order passed to them, but for now we would hard code anything we needed.

 

Broadcasting a change

This is where about half the magic happens.  The markup itself is uninteresting with only a single dropdownlist which will display the OrderIDs.  Lets look at the codebehind though.

Ignoring the code which populates the dropdownlist, let’s look at the code specific to this example.

Public Delegate Sub BroadcastSelectedOrderEvent(SelectedOrder As Order)

Public Event BroadcastSelectedOrder As BroadcastSelectedOrderEvent

    Private Sub Orderscombo_SelectedIndexChanged(sender As Object, e As EventArgs) Handles Orderscombo.SelectedIndexChanged
        BroadcastValues(sender)
    End Sub

    Private Sub BroadcastValues(ByVal sender As DropDownList)
        Using ctx As New EverymanDatabaseEntities

            Dim _Order As Order = ctx.Order.Where(Function(x) x.OrderId = sender.SelectedValue).SingleOrDefault
            RaiseEvent BroadcastSelectedOrder(_Order)

        End Using
    End Sub

 

We create a Delegate method that exposes a Broadcast event and Pass along an entire object of type Order.

We create a Public Event that exposes that a Broadcast has occured (something has been picked from the dropdownlist) that the Parent page can see.

When SelectedIndexChanged fires, we call BroadcastValues which creates the object of type Order based on the dropdownlist’s SelectedItem.value.

Lastly, we manually Raise and Event called BroadcastSelectedOrder and pass it the Order Object.

In order for the line above to work, we need a new line on the Parent Page’s Page_Load which creates a Handler for the Event of the Header’s Dropdownlist and handles it in the Child control.

 

AddHandler HeaderControl.BroadcastSelectedOrder, AddressOf ProductsControl.ReceiveSelectedOrderBroadcast

 

Now quite clear yet?  It’s ok, it took us a day or two to come up with this scenario.  Essentially, the Default page is given Event Handlers for the Dropdownlist in its child control, which are tactfully handled in THEIR child controls…its pretty kool actually.  Trust me.

 

Receiving the Broadcast

In the Child controls of the Header control, all we really need this to receive the Broadcast, as indicated in the Default Page_Load .

    Public Sub ReceiveSelectedOrderBroadcast(ByVal _SelectedOrder As Order)

        FilltheRepeater(_SelectedOrder)

    End Sub

 

That’s pretty much it.  At this point, the Order is passed onto the child control.  Obviously there’s still a lot of work to be done, but as far as passing the information down from the Header control, we’re done.DelegateMethods-2

 

Conclusion

Using a Delegate was a no-brainer once the project started getting more and more complex and it caused us to step back and look at what information needed to be shared across the 6 or so Child controls we had.  Once we had taken the time to assemble the data that needed to be passed down to the child controls, the individual programmers were able to work in silos, knowing fully that the code would work upon checkin because their code was reacting to a change that was handed down to them on a silver platter.

I’ve made an entire solution available with a fully functioning example to get you started off on the right foot.

If you have any suggestions, tips or comments, please feel free to comment below and I’ll respond as soon as I can.  Please be sure to download the Zip at the bottom of this article, it contains all the Source code needed for this project.

If you found this article helpful, please consider clicking on one of my sponsors, it’s what pays the bills here.

Happy Coding!

Using the Telerik RadComoBox ItemsRequested to create an autocomplete

 

I’ve been using the Telerik Ajax controls for about a year and a half now and I’m still regularly blown away by the work these controls save me every time I use them.  Today I thought I’d look at the radcombox and the ItemsRequested event.  Essentially, this event allows you to create an AutoComplete control without implementing a web service (see http://everymanprogrammer.com/index.php/autocomplete-dropdown-made-easy-a-beginners-tutorial/ ).

 

Getting Started

Obviously you’ll need a copy of the latest Telerik Ajax controls (http://www.telerik.com/).  Now, let’s add a form and create a radcombobox with the appropriate markup (http://www.telerik.com/products/aspnet-ajax/combobox.aspx).

    <telerik:RadScriptManager ID="RadScriptManager1" runat="server">
    </telerik:RadScriptManager>
    <div>
        <telerik:RadComboBox ID="Statescombo" runat="server" DropDownWidth="450" EmptyMessage='-- Please Select --' Width="150"
                    EnableLoadOnDemand="true" ItemsPerRequest="10" DataTextField="Name" DataValueField="ID"  
                    HighlightTemplatedItems="true" ExpandDelay="0" ExpandAnimation-Duration="0" CollapseAnimation-Duration="0" 
                    CollapseDelay="0" LoadingMessage="Loading ...">
        </telerik:RadComboBox>    
    </div>

 

The above is fairly straightforward, we enable the LoadOnDemand and then provide the column names and some animation info.

 

CodeBehind

 Private Sub Statescombo_ItemsRequested(sender As Object, e As Telerik.Web.UI.RadComboBoxItemsRequestedEventArgs) Handles Statescombo.ItemsRequested

        With Statescombo
            .DataSource = fillStates.ToList
            .DataValueField = "ID"
            .DataTextField = "Name"
            .DataBind()
        End With

    End Sub

    Private Function fillStates() As List(Of States)

        Dim _States As New List(Of States)
        _States.Add(New States("AL", "Alabama"))
        _States.Add(New States("AL", "Alabama"))
        _States.Add(New States("AK", "Alaska"))
        _States.Add(New States("AZ", "Arizona"))
        _States.Add(New States("AR", "Arkansas"))
        _States.Add(New States("CA", "California"))
        _States.Add(New States("CO", "Colorado"))
        _States.Add(New States("CT", "Connecticut"))
        _States.Add(New States("DE", "Delaware"))
        _States.Add(New States("FL", "Florida"))
        _States.Add(New States("GA", "Georgia"))
        _States.Add(New States("HI", "Hawaii"))
        _States.Add(New States("ID", "Idaho"))
        _States.Add(New States("IL", "Illinois"))
        _States.Add(New States("IN", "Indiana"))
        _States.Add(New States("IA", "Iowa"))
        _States.Add(New States("KS", "Kansas"))
        _States.Add(New States("KY", "Kentucky"))
        _States.Add(New States("LA", "Louisiana"))
        _States.Add(New States("ME", "Maine"))
        _States.Add(New States("MD", "Maryland"))
        _States.Add(New States("MA", "Massachusetts"))
        _States.Add(New States("MI", "Michigan"))
        _States.Add(New States("MN", "Minnesota"))
        _States.Add(New States("MS", "Mississippi"))
        _States.Add(New States("MO", "Missouri"))
        _States.Add(New States("MT", "Montana"))
        _States.Add(New States("NE", "Nebraska"))
        _States.Add(New States("NV", "Nevada"))
        _States.Add(New States("NH", "New Hampshire"))
        _States.Add(New States("NJ", "New Jersey"))
        _States.Add(New States("NM", "New Mexico"))
        _States.Add(New States("NY", "New York"))
        _States.Add(New States("NC", "North Carolina"))
        _States.Add(New States("ND", "North Dakota"))
        _States.Add(New States("OH", "Ohio"))
        _States.Add(New States("OK", "Oklahoma"))
        _States.Add(New States("OR", "Oregon"))
        _States.Add(New States("PA", "Pennsylvania"))
        _States.Add(New States("RI", "Rhode Island"))
        _States.Add(New States("SC", "South Carolina"))
        _States.Add(New States("SD", "South Dakota"))
        _States.Add(New States("TN", "Tennessee"))
        _States.Add(New States("TX", "Texas"))
        _States.Add(New States("UT", "Utah"))
        _States.Add(New States("VT", "Vermont"))
        _States.Add(New States("VA", "Virginia"))
        _States.Add(New States("WA", "Washington"))
        _States.Add(New States("WV", "West Virginia"))
        _States.Add(New States("WI", "Wisconsin"))
        _States.Add(New States("WY", "Wyoming"))

        Return _States.ToList

    End Function

    Public Class States
        Public Sub New(ByVal ID As String, ByVal Name As String)
            _ID = ID
            _Name = Name

        End Sub

        Private _ID As String = String.Empty
        Public Property ID() As String
            Get
                Return _ID
            End Get
            Set(ByVal value As String)
                _ID = value
            End Set
        End Property

        Private _Name As String = String.Empty
        Public Property Name As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set

        End Property

    End Class

 

So, without handholding too much, I’ve created a States Object, if you step through the code, you’ll notice that the statescombo.ItemsRequested event is only fired once the combobox is actually clicked on.  This is interesting because it means that your Page_Load is not used and therefore the page itself will load faster.  You’ll note that fillStates literally does nothing but create a List and return it as the DataSource.

As it stands however, the combobox is nothing more than a standard combobox. itemsRequestedFull

We only want the combobox to return content once the user has started entering text, to do this, we merely surround the itemsRrequested code with an If statement.

If Not e.Text = "" Then

End If

 

This still doesn’t give us everything we want yet.  The most important piece of the puzzle is sending what the user is typing into the combobox to the query and filteribng based on (in this example) starts with.

Let’s implement that now.

 

            Dim _States As List(Of States) = (From v In fillStates()
                                                Where v.Name.StartsWith(e.Text) Take 10
                                                 Order By v.Name).ToList

 

Again, the statement above is quite clear when taken on its own like this.  We create a new list of States, we fill it from the function and return the top 10 records where the Name starts with whatever is passed to the function from what the user is typing and they are returned in alpha order, based on the name.  Lastlly we simply replace the .DataSource with the new, filtered list.

So, the code now looks like this

    Private Sub Statescombo_ItemsRequested(sender As Object, e As Telerik.Web.UI.RadComboBoxItemsRequestedEventArgs) Handles Statescombo.ItemsRequested
        If Not e.Text = "" Then

            Dim _States As List(Of States) = (From v In fillStates()
                                                Where v.Name.StartsWith(e.Text) Take 10
                                                 Order By v.Name).ToList
            With Statescombo
                .DataSource = _States
                .DataValueField = "ID"
                .DataTextField = "Name"
                .DataBind()
            End With

        End If
    End Sub

Conclusion

I think the benefits of not loading ‘another’ control at Page_Load is obvious.  The second benefit to this type of code becomes obvious when you have to populate something like a List of Countries, or perhaps Product codes where there could literally be thousands to display.

If you have any suggestions, tips or comments, please feel free to comment below and I’ll respond as soon as I can.  Please be sure to download the Zip at the bottom of this article, it contains all the Source code needed for this project.

If you found this article helpful, please consider clicking on one of my sponsors, it’s what pays the bills here.

Happy Coding!

Introduction to Using the Entity FrameWork – Part 2

 

 

In my continuing series on using the Entity Framework, I’ve taken my first Tutorial ‘Introduction to Using the Entity FrameWork – Part 1′ and have started to expand on some of the possibilities when using EF and LinQ.

 

 Getting Started

 

I thought I would create a simple example that would highlight the simplicity built into EF got querying a database.

The first thing we’ll do is create two classes, called Clients and ClientPurchases, this will allow us to pass the Client data back and forth across the application.

 

 

Clients.vb

Public Class Clients
    Public Sub New(ByVal ClientID As Integer, ByVal FullName As String)
        _ClientID = ClientID
        _FullName = FullName

    End Sub

    Sub New()
        _ClientID = ClientID
        _FullName = FullName
    End Sub

    Private _ClientID As Integer = 0
    Public Property ClientID() As Integer
        Get
            Return _ClientID
        End Get
        Set(ByVal value As Integer)
            _ClientID = value
        End Set
    End Property

    Private _FullName As String = String.Empty
    Public Property FullName As String
        Get
            Return _FullName
        End Get
        Set(ByVal value As String)
            _FullName = value
        End Set

    End Property

End Class

ClientPurchases.vb

Public Class ClientPurchases
    Public Sub New(ByVal ClientID As Integer, ByVal ClientName As String, ByVal OrderTotal As Double)
        _ClientID = ClientID
        _ClientName = ClientName
        _OrderTotal = OrderTotal
    End Sub

    Sub New()

    End Sub

    Private _ClientID As Integer = 0
    Public Property ClientID() As Integer
        Get
            Return _ClientID
        End Get
        Set(ByVal value As Integer)
            _ClientID = value
        End Set
    End Property

    Private _ClientName As String = String.Empty
    Public Property ClientName As String
        Get
            Return _ClientName
        End Get
        Set(ByVal value As String)
            _ClientName = value
        End Set

    End Property

    Private _OrderTotal As Double = 0.0
    Public Property OrderTotal() As Double
        Get
            Return _OrderTotal
        End Get
        Set(ByVal value As Double)
            _OrderTotal = value
        End Set

    End Property
End Class

 

Next we’ll change the HTML markup from our previous example slightly.

           <asp:DropDownList ID="clientCombo" runat="server" AutoPostBack="true"></asp:DropDownList>
            <div style="margin-top:10px;" />
            <asp:Repeater ID="Repeater1" runat="server" >
                <HeaderTemplate>
                    <table class="gridtable">
                        <tr>
                            <th>Client Name </th>
                            <th>Client ID</th>
                            <th>Order Total</th>

                        </tr>
                </HeaderTemplate>
                <ItemTemplate>
                    <tr>
                        <td><%# Eval("ClientID")%></td>
                        <td><%# Eval("ClientName")%></td>
                        <td><%# Eval("OrderTotal")%></td>
                    </tr>
                </ItemTemplate>
                <FooterTemplate>
                    <tr>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                    </tr>
                    <tr>
                        <td><strong>Total</strong></td>
                        <td></td>
                        <td><asp:Label ID="lblOverallTotal" runat="server" Text='<%# Eval("OverallTotal")%>' Font-Bold="true"></asp:Label></td>
                    </tr>
                    </table>   
                </FooterTemplate>

            </asp:Repeater>

 

The Code Behind

 

To start, let’s fill a DropDownList from the names in the database, however let’s use the Entity Framework to do some of the heavy lifting for us.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not Page.IsPostBack Then
            Example1()
        End If

    End Sub

    Private Sub Example1()
        Using ctx As New EverymanDatabaseEntities

            Dim _clients As List(Of Client) = ctx.Client.OrderBy(Function(x) x.LastName).ThenBy(Function(x) x.FirstName).ToList
            Dim FullNames = From b In _clients
                Select New Clients With {
                      .ClientID = b.ClientId,
                      .FullName = b.LastName & ", " & b.FirstName
                }

            With clientCombo
                '.DataSource = ctx.Client.OrderBy(Function(x) x.LastName).Take(25).ToList
                .DataSource = FullNames.Take(25).ToList
                ' .DataTextField = "LastName"
                .DataTextField = "FullName"
                .DataValueField = "ClientId"
                .DataBind()
                .Items.Insert(0, New ListItem("--Please Select--", "-1"))
            End With
        End Using
    End Sub

 

Lets take a look at the code above.  We’re creating a list of the Object of type Client, ordered by LastName, then by FirstName, pretty straightforward right?   Now normally we could just bind the List (Of Client) directly to the dropdownlist (see the REM’d out code), but I wanted to display the Value in the Dropdown as ‘Lastname, Firstname’.  Now, if we tried to Bind more than one column to the DataTextField, it’ll bomb.  That’s ok, we can work with that.

To do, we’ll take the Class Object Client called _clients and turn into an anonymous Type.  Essentially what this means is we can assemble the object on the fly, doing this allows us to do ‘.FullName = b.LastName & “, ” & b.FirstName’.  So let’s read the code.

Create a List of Client, order by lastname, firstname –  Dim _clients As List(Of Client) = ctx.Client.OrderBy(Function(x) x.LastName).ThenBy(Function(x) x.FirstName).ToList –  Check

Create anonmyous object called FullNames with new ColumnNames – Dim FullNames = From b In _clients
Select New Clients With {
.ClientID = b.ClientId,
.FullName = b.LastName & “, ” & b.FirstName
}

Check

Bind our DropDownList to the dataSource and for the fun of this example, limit the number of records returned to 25 (think SELECT TOP 25). Check

Bind our anonymous columns to the Text and Value colums –    .DataTextField = “FullName”, .DataValueField = “ClientId” – Check

Lastly, insert a SELECT option into the dropdownlist, setting its Index (position) at 0 so that it ALWAYS appears at the top of the list – Check

At this point, we have a fully function dropdownlist, bound to our Anonymous List. Dropdownlist

 

Ok, time for the repeater

 

Now, let’s add the code to fill the Repeater.  Now, we could setup the code to fill the Repeater when something is picked in the dropdownlist, but that means initially the repater would be empty, and well, that’s ugly.  So, instead, let’s do this, we;ll load all the records in the repeater and then just rebind it when something is picked in the dropdownlist.  How’s that?  Oh, and this let;s us show off some interesting Entity Framework math juice.

So, first thigs first, let’s create a function to fill the repeater.  We know we’ll want the function to pull a ceetain record when the dropdownlist fired, but that initially it’ll pass nothing, so let’s do this.

            FilltheRepeater(Nothing)

 

Ok, next, let’s work with the Repeater.

 Private Sub FilltheRepeater(Optional ByVal ClientId As Integer = Nothing)
        Repeater1.DataSource = returnPurchases(ClientId)
        Repeater1.DataBind()
    End Sub

    Private Function returnPurchases(ByVal ClientId As Integer) As List(Of ClientPurchases)

        Using ctx As New EverymanDatabaseEntities

            Dim q As IQueryable(Of Order) = ctx.Order.OrderBy(Function(x) x.Client.LastName).ThenBy(Function(x) x.Client.FirstName)
            If ClientId > 0 Then
                q = q.Where(Function(x) x.ClientId = ClientId)
            End If

            Dim _ClientPurchases = From b In q
                Select New ClientPurchases With {
                      .ClientID = b.ClientId,
                      .ClientName = b.Client.LastName & ", " & b.Client.FirstName,
                      .OrderTotal = b.OrderTotal
                }
            Return _ClientPurchases.Take(25).ToList

        End Using

    End Function

 

Ok, so what’s happening?  Well, the FilltheRepeater routine is set to recieve an ID from the dropdownlist, on first load it’ll pass nothing.  This is good.  Ok, next, we’ll use a function to pass the ID from the dropdownlist (or NOTHING) to a function that will create an object of ClientPurchases for us.

So, let’s pull a list of Orders directly from the Database, this will essentially return the entire related table and all data.  We declare it as an IQueryAble Type so that we may Query against it, right?

Now, let’s see if an ID was passed from the DropDownList.  We know that on first load it will be Nothing, so let’s handle this.

If ClientId > 0 Then
      q = q.Where(Function(x) x.ClientId = ClientId)
End If

So, at this point, we still have an object with EVERY record in the Orders database, that’s good, that’s what we wants on first load.  Next, let’s populate the object that will finally be return to the Repeater.

Dim _ClientPurchases = From b In q
Select New ClientPurchases With {
.ClientID = b.ClientId,
.ClientName = b.Client.LastName & “, ” & b.Client.FirstName,
.OrderTotal = b.OrderTotal
}
Return _ClientPurchases.Take(25).ToList

 

As above, we use an Anonymous Type to allow us to create a ClientName column from the FirstName and LastName columns in the Client object.  Lastly, once we have a fully assembled Anonymous object, I’ll limit the return to 25 again.

At this point we have a fully functioning dropdownlist and populated repeater but the Dropdownlist doesn’t yet select anything. Dropdownlist_repeater

 

 

 

 

 

    Private Sub clientCombo_SelectedIndexChanged(sender As Object, e As EventArgs) Handles clientCombo.SelectedIndexChanged

        Dim comboBox As DropDownList = DirectCast(sender, DropDownList)
        FilltheRepeater(comboBox.SelectedItem.Value)

    End Sub

 

That’s it, the Repeater is now fully functional.  But it’s not totally cool just yet.  One last piece of the puzzle, in order to show off some Entity Framework Math.

Let’s add that final piece of the puzzle.

 

    Private Sub Repeater1_ItemDataBound(sender As Object, e As RepeaterItemEventArgs) Handles Repeater1.ItemDataBound

        If e.Item.ItemType = ListItemType.Footer Then

            Dim lblOverallTotal As Label = CType(e.Item.FindControl("lblOverallTotal"), Label)
            lblOverallTotal.Text = String.Format("{0:$###,##0.00}", returnOverAllPurchases())

        End If

    End Sub

 Private Function returnOverAllPurchases() As Double

        Dim myReturn As Double = 0.0

        Using ctx As New EverymanDatabaseEntities

            Dim _ClientPurchases As List(Of ClientPurchases) = returnPurchases(clientCombo.SelectedItem.Value)
            Dim OverallOtotal As Double = _ClientPurchases.Sum(Function(x) x.OrderTotal)

            myReturn = OverallOtotal

        End Using

        Return myReturn

    End Function

By using the Item_DataBound event of the Repeater, we’ll find a Label in the footer and populate it with a SUM of the Totals. The interesting thing is we don’t need different code for whether it’s all the Orders or a subset based on a Selected name from the dropdownlist.

The returnOverAllPurchases will create a List of ClientPurchases, based on whether anything was picked in the dropdownlist, so it will either be a full list of the order, or a simple subset of orders based on the name picked.  Then we create a Double which is a SUM of ALL the OrderTotals for that list (_ClientPurchases.Sum(Function(x) x.OrderTotal)).

That’s IT!  Calling SUM against the appropriate column in the LIST does the math for us.Dropdownlist_repeater_sum

 

 

 

 

Conclusion

 

That about covers it for now.  I know these are pretty simplistic examples but they are fairly ‘real world’ as I do this type of thing fairly often.  Use the Entity Framework, let it do your dirty work, your heavy lifting.  You’ll be glad you did.

If you have any suggestions, tips or comments, please feel free to comment below and I’ll respond as soon as I can.  Please be sure to download the Zip at the bottom of this article, it contains all the Source code needed for this project.

If you found this article helpful, please consider clicking on one of my sponsors, it’s what pays the bills here.

Happy Coding!

 

Introduction to Using the Entity FrameWork – Part 1

 

I’ve been using the Entity Framework for just under 2 years now and I’m telling you, if you haven’t tried it yet, you’re truly missing out.  The idea behind the Entity FrameWork was to allow you to manipulate the data in your database without ever actually writing any Stored Procedures or T-SQL.  You can still access or use Stored Procedures, Views, etc. if you want to but in almost 2 years using Entity FrameWork, I haven’t written so much as a single Stored Procedure.

Getting Started

Ok, before we go too far, we need to ensure that you’ve got the Entity FrameWork installed on your pc.  Most recent installs of Visual Studio 2012+ will handle this for you but if you’re not sure, take a look at this article, it will walk you through a fairly painless installation (How to configure and use Entity Framework).

How to proceed – Preparing a Data Store

We’re going to begin this Tutorial by creating a simple Web Project and choose an Empty Web Forms template. Web Forms

 

 

 

 

 

Add a DatabaseFrom within your empty Template, right-click in your Solution Explorer window, hit Add – New Item and under the DATA tab, choose SQL Server Database and for this example we’ll name it EverymanDatabase.mdf.

 

 

 

 

In most cases, Visual Studio will understand that you are adding a SQL database and ask if you want to create an App_Data folder to house it, choose yes. 3

 

 

 

 

 

You should now see a new Database appear in the App_Data called EverymanDatabase.mdf and a EverymanDatabase.ldf (lock file).  A double click of the EveryManDatabase.mdf file should open the Database structure in your Server Explorer Window4.  You can peruse the Database if you wish but in its current state its useless, so lets add some data.

 

 

 

 

Please follow the instructions at the following location (Create a Sample SQL Database in Less Than 2 Minutes) in order to add some DummyData or you may use you own Data, though beware the queries at the bottom of the project are Data Specific.

 

Right click on the Database Name and choose NEW QUERY.  You’ll want to remove the USE FABRICS at the top of the very long T-SQL and replace it with the name of your Database, in most cases you can do this be deleting USE FRABRICS and then use the dropdown that appears just above the Query screen to point to your 5database, in my case it looked like this.

 

6Use the Green arrow on the same line as the dropdown to EXECUTE the script.  Beware it may take a minute or so and when its done, you should Refresh your Database with a Right-Click on the Database name and choose Refresh.  Your database should now look like this

 

 

 

 

Creating a DataModel

Up until now we’ve done nothing specific to Entity Framework, we’ve only prepared our Project with the basic tools needed to read from a database.  The following steps are specific to using the Entity Framework.

 

In your Solution Explorer, right-click and choose Add – New Item and choose ADO.NET Entity Data Model and give it a name, for this tutorial we’ll call it EverymanDataModel.edmx.  7

 

 

 

 

 

 

 

This will start a mini-wizard which will prompt you for some very basic information.8  In this case, we want the system to create a DataModel based on the data structure that already exists in our EveryManDatabase, so we choose Generate From Database.

 

 

 

 

Next, Visual Studio is asking which Database it should connect to, in this example, we’ll use the Database we just created.  It is the only Database in the app therefore 9Visual Studio is smart enough to choose it for us.  As well, Visual Studio will create a Connection String in the Web.Config on our behalf.  We must also name the Connection String, for this example, we’ll call it EveryManDatabaseEntities.

 

 

 

 

10In some cases, you’ll be prompted for the version of Entity FrameWork to use, I will choose 5.0 for this example.  I have not begun to use 6.0 yet because it is not properly supported in MVC yet.

 

 

 

 

The last page of the Wizard is the most import, you’ll be prompted for which Data you would like to return from the Database, in most cases you’ll choose TABLES but 11you could also choose Views or Stored Procedures and Functions (if any existed).  I usually select the second and third check boxes but I typically deselect the first check box.  Checking this check box will change some of the names in the DataModel, ie USER would become USERS, SHIPMENTS becomes SHIPMENT and I tend to find that confusing at times but it’s totally your call.

 

The system will work for anywhere up to ten seconds or so and then present you with a beautiful, visual representation of your Data Model.  This will include the Relations from Table to Table, in our example, from the Client to the Products they’ve ordered.

Why do we care?  Well the truly amazing thing is that through proper use of the Foreign Keys, you can pull your Data from the Data Base (data model) as an Object.  What does this mean exactly?  Well, though not yet a real object (we’ll look at that in a later article), the DataModel assembles the Data for you based on the Foreign Keys, you these are very important.  If properly setup, you’ll be able to pull an object from your Model an pass it back and forth throughout your app without return to the Database, except for additional CRUD operations (Create, Read, Update, Delete (in case you ever wondered)).

If you double-click on the new EverymanDataModel.edmx file, you’ll see how the DataModel represents your Database, as well as the Relations within the tables. 12 Additionally, you’ll find Classes written for Product, Occupation, etc. built based on the data schema found in the database.

 

 

 

 

Next, if you take a look in you web.config, you’ll see that the Connection String we saw being created during the DataModel Wizard has been added here.

13

 

Getting on with it

Ok, if you’re like most programmers I know, you’ve skipped past most of the above and want to see how the code works.  Fine.  Be that way, let’s get at it.

Let’s create a new Web Form called Default.aspx and lets add some markup.  In this example, I’ll use a simple repeater to pull some data from the Products database.

 

    <asp:Repeater ID="Repeater1" runat="server"  >
        <HeaderTemplate>
            <table style="border:solid 1px;">
                <tr>
                    <th>   Product ID
                    </th>
                    <th>   Product Name
                    </th>
                </tr>
        </HeaderTemplate>
        <ItemTemplate>
            <tr>
                <td>
                    <%# Eval("ProductId") %>
                </td>
                <td>
                    <%# Eval("ProductName") %>
                </td>
                <td>
            </tr>
        </ItemTemplate>
        <FooterTemplate>
            </table>
        </FooterTemplate>
    </asp:Repeater>

 

So, as we can, about as simple as it gets, a Repeater control with a column for the Product ID and a column for the Product Name, nothing new, nothing to see here folks.  Ok, time to see some magic.  Let’s hit up some code behind.

So, the very first thing we need to do is tell Visual Studio that we want to use the Entity FrameWork, this is as complicated as adding Imports System.Data.Entity, this will of course load all the necessary libraries and/or references needed.

 

Imports System.Data.Entity

 

Next, in our Page Load, lets call a SubRoutine to fill our Repeater.

 

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Example1()

    End Sub

 

Now, lets have some fun.

    Private Sub Example1()
        Using ctx As New EverymanDatabaseEntities
            Repeater1.DataSource = ctx.Product.ToList
            Repeater1.DataBind()
        End Using
    End Sub

 

That’s it.  Yup, that’s it.  Don’t believe me, RUN the project, go on, hit F5!!

Ok fine, i suppose we can explain a few things.

So, from MSDN

‘A Using block behaves like a Try…Finally construction in which the Try block uses the resources and the Finally block disposes of them. Because of this, the Using block guarantees disposal of the resources, no matter how you exit the block. This is true even in the case of an unhandled exception, except for a StackOverflowException.
The scope of every resource variable acquired by the Using statement is limited to the Using block.
If you specify more than one system resource in the Using statement, the effect is the same as if you nested Using blocks one within another.
If resourcename is Nothing, no call to Dispose is made, and no exception is thrown.’

So, let’s be clear here, we are going to open a Connection to a newly Instantiated instance of the Connection String we create for the Data Model, which we name ctx (in many instances its called ctx or context (call it foo if you like)), called EveryManDatabaseEntities.

This gives you access to everything inside the Data Model.  So, very simply, in Example 1, we are using LINQ (Language-Integrated Query) to query the Data Model and return every row in the the object Product, this results in a list being produced from the Products table in the Database.

The End Using closes your Connection and you no longer have access to the Data Model content.

15If we run Example 2 instead, we can use LINQ to Order the Product Name list by Alphabetical Order.

If we run Example 3, we can use Linq to return only the first 50 records of the Products table.  This LINQ query would basically be translated to SQL as SELECT TOP 50 FROM Products.

 

Examples

 

    Private Sub Example2()

        Using ctx As New EverymanDatabaseEntities
            Repeater1.DataSource = ctx.Product.OrderBy(Function(x) x.ProductName).ToList
            Repeater1.DataBind()
        End Using
    End Sub

    Private Sub Example3()

        Using ctx As New EverymanDatabaseEntities
            Repeater1.DataSource = ctx.Product.OrderBy(Function(x) x.ProductName).Take(50).ToList
            Repeater1.DataBind()
        End Using
    End Sub

Conclusion

Obviously I’ve only just touched on what can be done with Entity FrameWork and Linq.  In future articles I’ll expand by getting into Updating the Data Model, as well as implementing a full CRUD operation with a grid, all without a single line of SQL.

If you have any suggestions, tips or comments, please feel free to comment below and I’ll respond as soon as I can.  Please be sure to download the Zip at the bottom of this article, it contains all the Source code needed for this project.

If you found this article helpful, please consider clicking on one of my sponsors, it’s what pays the bills here.

Happy Coding!

Using the RadComboBox with a Templated Layout

So I thought I would just change gears here a little and spend some time with a much overlooked control.  The RadComboBox is a very complex piece of kit but tends to be overlooked because its ‘just a dropdown’.  In this article I want to touch on just one of the many design capabilities of the RadComboBox, that of the ItemTemplate.

Getting Started

For this example, I want to assemble a dropdown with the names of some garages where I can get my car fixed.  In some instances though, you may find yourself wanting to present the user with some additional information and this is just one of many ways we can do it.

Let’s build the RadComboBox:

Step 1. Using a Template –

<telerik:RadComboBox ID=”cboVendorNumber” runat=”server” Width=”150px” Height=”150″ DropDownWidth=”450″ AutoPostBack =”true”
DataTextField=”VendorName” EmptyMessage=” – Please Select -” LoadingMessage=”Loading …”>

EmptyComboBoxTypically at this point you would close the markup with </telerik:RadComboBox> but not today. Inside the RadComboBox we’re going to build a 2 column table with a common header.  After the Header we’re going to create an ItemTemplate, this Template is essentially a row that’s treated as though it’s inside a Rep[eater.  You’ll see what I mean.

The Markup and Codebehind

Step 2. The Markup –  You’ll see from the below code that we build the Header using Labels with a Static text, this is because the header does not change throughout the control’s life cycle.  The ItemTemplate is built using two DataBound controls, each control is bound to a column in the DataSource.  A new row is automatically built for each row in the DataSource.  Easy Peasy.  I added some god awful CSS to make the dropdown a little easier to read.

At this point, the MarkUp is complete but not yet functional because we haven’t added the code behind.

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
<style>
    .comboBoxListItem 
    { 
        background-color: #333; 
        color:#FFF;
    } 

    .alternatingComboBoxListItem 
    { 
        background-color: #FFF; 
        color: #333;
    } 
</style>
</head>
<body>

    <form id="form1" runat="server">
    <telerik:RadScriptManager ID="RadScriptManager1" runat="server">
    </telerik:RadScriptManager>

    <div>

    <telerik:RadComboBox ID="cboVendorNumber" runat="server" Width="150px" Height="150" DropDownWidth="450" AutoPostBack ="true"  
                                 DataTextField="VendorName" EmptyMessage=" - Please Select -" LoadingMessage="Loading ...">
        <HeaderTemplate>
        <div style="width: 420px; height: 15px;">
            <div style="display: block; float: right; color: rgb(0, 21, 110) !important;">
                <asp:Label ID="lblHeader" runat="server" />
            </div>
        </div>
        <div style="width: 420px;">
            <div style="width: 150px; float: left; ">
                <asp:Label ID="lblVendor" runat="server" Text="Vendor" Font-Bold="true"/>
            </div>
            <div style="width: 200px; float: right; ">
                <asp:Label ID="lblVendorDesc" runat="server" Text="Vendor Desc" Font-Bold="true"  />
            </div>
        </div>
        </HeaderTemplate>
        <ItemTemplate>   
            <!-- Row -->
            <div style="width: 420px;">
                <div style="width: 150px; float: left; ">
                     <asp:Label ID="VendorName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "VendorName").ToString()%>'></asp:Label>         
                </div>
                <div style="width: 200px; float: right; ">
                    <asp:Label ID="VendorDesc" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "VendorDesc").ToString()%>'></asp:Label>    
                </div>
            </div>
            <!-- End of row --> 
        </ItemTemplate>
        </telerik:RadComboBox>

        <asp:Label ID="lblSummary" runat="server" Font-Bold="true"  />

    </div>
    </form>
</body>
</html>

 

PopulatedComboboxThe code behind listed below does a number of things, as usual I’m not going to hand hold for each little piece of whatever that is happening as its straightforward enough for most anyone to understand, novice or not.  However, let’s look at one or two pieces of the puzzle.

Firstly, ‘Always check for PostBack’…god knows how many times I’ve asked myself, why is my SelectedItem.Value always empty?!?!  Check for PostBack.

 

Secondly, we’re using the Databound event to check the Index of the current row, we’re using this method to assign a CSS style so that we can attain an ‘Alternating row’ look because for some reason, this isn’t built into the RadcomboBox.

CompletedComboboxLastly, we use the SelectedIndexChanged Event to determine that something unique has been picked in the RadComboBox and therefore we return the SelectedItem.Text for that row.  In many instances you would use this type of even to acquire the ID of whatever is in the row.

Imports Telerik.Web.UI

Public Class _Default
    Inherits System.Web.UI.Page

#Region "Page Methods"
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If Not Page.IsPostBack Then
            cboVendorNumber.DataSource = GetVendorList()
            cboVendorNumber.DataBind()
        End If

    End Sub

    Private Function GetVendorList() As List(Of Vendors)

        Dim Vendors As New List(Of Vendors)
        Vendors.Add(New Vendors(1, "My Automotive", "Automobile Repair"))
        Vendors.Add(New Vendors(2, "Big Garage Inc.", "All your Car repairs here"))
        Vendors.Add(New Vendors(3, "Total FiX", "We do all FiXes"))
        Vendors.Add(New Vendors(4, "Elvis Garage", "No Blue Suede Shoes here"))

        Return Vendors.ToList

    End Function

    Private Sub cboVendorNumber_DataBound(sender As Object, e As EventArgs) Handles cboVendorNumber.DataBound
        For Each rcbi As RadComboBoxItem In cboVendorNumber.Items
            If rcbi.Index Mod 2 = 0 Then
                rcbi.CssClass = "comboBoxListItem"
            Else
                rcbi.CssClass = "alternatingComboBoxListItem"
            End If
        Next
    End Sub

    Private Sub cboVendorNumber_SelectedIndexChanged(sender As Object, e As RadComboBoxSelectedIndexChangedEventArgs) Handles cboVendorNumber.SelectedIndexChanged
        lblSummary.Text = "You picked " & cboVendorNumber.SelectedItem.Text
    End Sub

#End Region

#Region "Vendors"
    Partial Public Class Vendors
        Public Sub New(ByVal ID As Integer, ByVal VendorName As String, ByVal VendorDesc As String)
            _ID = ID
            _VendorName = VendorName
            _VendorDesc = VendorDesc
        End Sub

        Private _VendorName As String = String.Empty
        Public Property VendorName() As String
            Get
                Return _VendorName
            End Get
            Set(ByVal value As String)
                _VendorName = value
            End Set
        End Property

        Private _VendorDesc As String = String.Empty
        Public Property VendorDesc() As String
            Get
                Return _VendorDesc
            End Get
            Set(ByVal value As String)
                _VendorDesc = value
            End Set
        End Property

        Private _ID As Integer = 0
        Property ID As String
            Get
                Return _ID
            End Get
            Set(ByVal value As String)
                _ID = value
            End Set
        End Property
    End Class
#End Region