Mark's Blog

.Net, C#, VB.Net, SQL, WPF, Silverlight, WCF, ASP.Net, EF

Thursday, June 23, 2011

Execute SQL with Entity Framework 4

Working with a client that is just moving over to EF4, they wanted some examples of executing dynamic SQL against their entity connection. The example below, taken from a console application, shows two ways to do this by using ExecuteStoreQuery or by extracting the SqlConnection from the EntityConnection. I’ve included examples in C# and VB.NET.

C#

using System;
using System.Configuration;
using System.Data.EntityClient;
using System.Data.SqlClient;
using ConsoleApplication5.Entity;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
            EntityConnection myConnection = new EntityConnection(ConfigurationManager.ConnectionStrings["SimpleDBEntities"].ConnectionString);

            //Using ExecuteStoreQuery in EF4.
            using (SimpleDBEntities se = new SimpleDBEntities(myConnection))
            {
                foreach(var tableNames in se.ExecuteStoreQuery("SELECT name FROM sys.tables"))
                {
                    Console.WriteLine(tableNames);
                }
            }

            //Extract the SqlConnection from the EntityConnection.
            SqlConnection mySqlConnection = myConnection.StoreConnection as SqlConnection;
            if (mySqlConnection.State != System.Data.ConnectionState.Open)
                mySqlConnection.Open();
            SqlCommand myCommand = new SqlCommand("SELECT name FROM sys.tables", mySqlConnection);
            using (var tableNames = myCommand.ExecuteReader())
            {
                while (tableNames.Read())
                {
                    Console.WriteLine(tableNames[0].ToString());
                }
            }

            mySqlConnection.Close();
            Console.ReadLine();
        }
    }
}

VB.NET

Imports System.Data.EntityClient
Imports System.Data.SqlClient
Imports System.Configuration

Module Module1

    Sub Main()
        Dim myConnection As New EntityConnection(ConfigurationManager.ConnectionStrings("SimpleDBEntities").ConnectionString)

        'Using ExecuteStoreQuery in EF4.
        Using se As New SimpleDBEntities(myConnection)
            For Each tableNames In se.ExecuteStoreQuery(Of String)("SELECT name FROM sys.tables")
                Console.WriteLine(tableNames)
            Next
        End Using

        'Extract the SqlConnection from the Entity Connection.
        Dim mySqlConnection As SqlConnection = TryCast(myConnection.StoreConnection, SqlConnection)
        If mySqlConnection.State <> System.Data.ConnectionState.Open Then
            mySqlConnection.Open()
        End If
        Dim myCommand As New SqlCommand("SELECT name FROM sys.tables", mySqlConnection)
        Using tableNames = myCommand.ExecuteReader()
            While tableNames.Read()
                Console.WriteLine(tableNames(0).ToString())
            End While
        End Using

        mySqlConnection.Close()
        Console.ReadLine()

    End Sub

End Module

Additional information can be found in MSDN at How to: Directly Execute Commands Against the Data Source

Thursday, June 9, 2011

WPF PasswordBox, MVVM, Data Binding, and VB.NET

I am currently working with a client that is writing a WPF application using VB.NET. One issue we ran into was that you cannot data bind to the password property of the PasswordBox since it is not a dependency property. I stumbled on the following article which details creating PasswordHelper class allowing data binding and keeping with the MVVM pattern. 

http://wpftutorial.net/PasswordBox.html

The example is written in C# so I had to port it to VB.NET for my project. Below is the VB.NET version of the PasswordHelper class. The XAML all works the same as the example.

Public NotInheritable Class PasswordHelper
    Private Sub New()
    End Sub
    Public Shared ReadOnly PasswordProperty As DependencyProperty = DependencyProperty.RegisterAttached("Password", GetType(String), GetType(PasswordHelper), New FrameworkPropertyMetadata(String.Empty, New PropertyChangedCallback(AddressOf OnPasswordPropertyChanged)))

    Public Shared ReadOnly AttachProperty As DependencyProperty = DependencyProperty.RegisterAttached("Attach", GetType(Boolean), GetType(PasswordHelper), New PropertyMetadata(False, New PropertyChangedCallback(AddressOf Attach)))

    Private Shared ReadOnly IsUpdatingProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsUpdating", GetType(Boolean), GetType(PasswordHelper))


    Public Shared Sub SetAttach(dp As DependencyObject, value As Boolean)
        dp.SetValue(AttachProperty, value)
    End Sub

    Public Shared Function GetAttach(dp As DependencyObject) As Boolean
        Return CBool(dp.GetValue(AttachProperty))
    End Function

    Public Shared Function GetPassword(dp As DependencyObject) As String
        Return DirectCast(dp.GetValue(PasswordProperty), String)
    End Function

    Public Shared Sub SetPassword(dp As DependencyObject, value As String)
        dp.SetValue(PasswordProperty, value)
    End Sub

    Private Shared Function GetIsUpdating(dp As DependencyObject) As Boolean
        Return CBool(dp.GetValue(IsUpdatingProperty))
    End Function

    Private Shared Sub SetIsUpdating(dp As DependencyObject, value As Boolean)
        dp.SetValue(IsUpdatingProperty, value)
    End Sub

    Private Shared Sub OnPasswordPropertyChanged(sender As System.Windows.DependencyObject, e As System.Windows.DependencyPropertyChangedEventArgs)
        Dim passwordBox As PasswordBox = TryCast(sender, PasswordBox)
        RemoveHandler passwordBox.PasswordChanged, AddressOf PasswordChanged

        If Not CBool(GetIsUpdating(passwordBox)) Then
            passwordBox.Password = DirectCast(e.NewValue, String)
        End If
        AddHandler passwordBox.PasswordChanged, AddressOf PasswordChanged
    End Sub

    Private Shared Sub Attach(sender As DependencyObject, e As DependencyPropertyChangedEventArgs)
        Dim passwordBox As PasswordBox = TryCast(sender, PasswordBox)

        If passwordBox Is Nothing Then
            Return
        End If

        If CBool(e.OldValue) Then
            RemoveHandler passwordBox.PasswordChanged, AddressOf PasswordChanged
        End If

        If CBool(e.NewValue) Then
            AddHandler passwordBox.PasswordChanged, AddressOf PasswordChanged
        End If
    End Sub

    Private Shared Sub PasswordChanged(sender As Object, e As RoutedEventArgs)
        Dim passwordBox As PasswordBox = TryCast(sender, PasswordBox)
        SetIsUpdating(passwordBox, True)
        SetPassword(passwordBox, passwordBox.Password)
        SetIsUpdating(passwordBox, False)
    End Sub
End Class

Wednesday, April 8, 2009

LINQ to XML and Namespaces

Today I was using a LINQ query to extract some data from an XML document but was not getting the expected results. I had used the same query pattern in the past and was puzzled to why it was not working.

I had the following XML.

   1: <SomeResults xmlns="http://www.someplace.com/api">
   2:   <Status>GOOD</Status>
   3: </SomeResults>

This was my original query.

   1: var courseStatusReqestResult = XDocument.Parse(@"<SomeResults xmlns=""http://www.someplace.com/api"">
   2:                                                     <Status>GOOD</Status>
   3:                                                  </SomeResults>");
   4:                                                  
   5: var response = from c in courseStatusReqestResult.Elements("SomeResults")
   6:                                              select c.Element("Status");
   7: response.Dump();
 
I was expecting the Status element to be returned, however response was null. After running some tests in LINQPad it turns out that the XML namespace attribute was throwing it off.
 
To fix this I had to add the namespace to the elements in the LINQ query.
 
   1: var courseStatusReqestResult = XDocument.Parse(@"<SomeResults xmlns=""http://www.someplace.com/api"">
   2:                                                     <Status>GOOD</Status>
   3:                                                  </SomeResults>");
   4:                                                  
   5: XNamespace ns = "http://www.someplace.com/api";
   6:  
   7: var response = from c in courseStatusReqestResult.Elements(ns + "SomeResults")
   8:                                              select c.Element(ns + "Status");
   9: response.Dump();
 
The results
 
image