Entity Framework 4.0 improvements

I’ve been a huge fan of LINQ to SQL. But EF 3.5 (first release) didn’t quite do it for me. I didn’t like the lack of support for foreign keys, no Single() LINQ support,

No Single support

An example of lack of foreign keys:

using(NorthwindEntities northwindEntities = new NorthwindEntities())
{
    Product p = new Product()
                {
                    Category = northwindEntities.Categories.Where(c => c.CategoryID == 1).First,
                    ProductName = "French fries",
                    UnitPrice = 20,
                    Discontinued = false,
                    QuantityPerUnit = "1 kg bag",
                    Supplier = northwindEntities.Suppliers.Where(s => s.SupplierID == 1).First

                };

    northwindEntities.AddToProducts(p);
    northwindEntities.SaveChanges();
}

As you can see you need to fetch  the category and the Supplier seperatly. You can’t just do CategoryID = 1

But when we launch the wizard for EF 4.0 we get this:

Include foreign key columns in the model

Which results in this:

using(NorthwindEntities northwindEntities = new NorthwindEntities())
{
    Product p = new Product()
                {
                    CategoryID = 1,
                    ProductName = "French fries",
                    UnitPrice = 20,
                    Discontinued = false,
                    QuantityPerUnit = "1 kg bag",
                    SupplierID = 1

                };

    northwindEntities.AddToProducts(p);
    northwindEntities.SaveChanges();
}

And there is Single support!

using(NorthwindEntities ne = new NorthwindEntities())
{
    var result = ne.Suppliers.Where(sup => sup.SupplierID == 1).Single();
}

So it just got a little more mature.

I’m hoping to be able to test it (and use it!) more in the future and new projects :)

Hope it helps

-Kristof

VB.NET: getting rid of With statements

Because With clutters your code, you get too much indentations and it removes readability. Now I saw code with 4 to 5 times nested With statements. Pure Horror. So my first job was to remove all these statements. But what if you get ambiguous Methods/Properties?

The documentation is clear on that:

However, because members of outer statements are masked inside the inner statements, you must provide a fully qualified object reference in an inner With block to any member of an object in an outer With block.

This means that in an inner with block you cannot access the members of the outer with block with the . qualified name. You need the full qualified name.

So when you need to de-with your code you start from the outside, taking the most outer block first, solving the references, building, removing the next one, and so on…

But you shouldn’t use With statements in the first place.

Just name your variable if you don’t want to enter the fully qualified name for every statement.

VB.NET, why I don’t like it

A little introduction: I’m working on some legacy VB.NET & Excel project. Pretty old stuff, quite the challenge of getting through the code. I’ve discovered multiple things about VB.NET which I didn’t knew (like the Microsoft.VisualBasic namespace, late binding, Option Strict).

The code I’m working with is cluttered with these kinds of abominations to the .NET framework. The Microsoft.VisualBasic is purely there for legacy VBA developers so that they can easily transfer to VB.NET.

But that doesn’t mean you need to use it in new projects (vbNullString? C’mon…)

I think that this namespace shouldn’t be offered by default anymore in new VB.NET projects. It should be there to merely quickly convert old VBA projects to .NET.

Late binding is another thing which I truly hate. It gets compiled to a bunch of reflection calls which make your code more error prone (no compiler checking!). Although I’ve managed to cast the System.__ComObject to it’s corresponding interface most of the time I had to resort to reflection one time myself (shame shame).

And finally there is this problem of cluttered code, for some reason, when I look at VB.NET code there is SO much text and all the essence get’s lost! While the C# code is so clean.

I will write a post about cleaning up With statements + best practices for nested With Statements from VB.NET code pretty soon.

Multi-Column ListView

Ever wanted to have a multi column ListView in WPF? It’s not that hard once you get to know WPF.

We take a ListView and set the ItemsPanel to UniformGrid:

<Window x:Class="ColumnTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <ListView x:Name="MyList">
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Columns="3" />
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
        <ListView.ItemTemplate>
            <DataTemplate>
                <Label Content="{Binding}" />
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Window>

 

And the backend code:

using System.Windows;

namespace ColumnTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();

            for (int x = 0; x <= 100; x++)
            {
                this.MyList.Items.Add(x);
            }
        }
    }
}

 

Which results in:

Uniform Grid Result

C# Late binding,

Today I was working on a project in VB.NET, which I had to convert to C#.

The problem was that they used late binding, they knew that some properties on objects existed, but they couldn’t be deduced by the compiler since the object’s type was Object.

For Example, let’s say we want to get the workbook of a chart.

A chart resides in a ChartObject (the chart.Parent) and a ChartObject resides in a Worksheet.

So chart.Parent.Parent returns the corresponding worksheet.

Like this:

Option Strict Off

Imports Microsoft.VisualBasic

Public Class TestClass
    Public Sub Test()
        Dim chart As Excel.ChartObject

        Dim workbook = chart.Parent.Parent
    End Sub

End Class

Now of course, if you compile this, it will work since Option Strict is off.

But when you set it on (or port it to C#) it won’t compile, since chart.Parent returns a type of Object. And the compiler cannot find the .Parent property on that Object, so we would need to cast to ChartArea to get the .Parent property appropriately, and then cast this result to an Excel.Worksheet.

Option Strict On

Imports Microsoft.VisualBasic

Public Class TestClass
    Public Sub Test()
        Dim chart As Excel.ChartObject

        Dim workbook As Excel.WorkSheet = CType(CType(chart.Parent, Excel.Worksheet).Parent, Excel.Workbook)
    End Sub

End Class

This will work.

Unfortunately sometimes there are properties you can set, but they don’t appear in your Intellisense, so you can’t get/set that property.

If you are using VB.NET with Option Strict Off this is no problem, but again: with Option Strict On or in C# it IS a problem.

Since the late binding internally uses Reflection I thought might fetch the PropertyInfo for that particular property and set it that way:

Dim propertyInfo As PropertyInfo = GetType(Excel.Chart).GetProperty("ThePropertyYouWant")

propertyInfo.SetValue(someChart, someValue, BindingFlags.SetProperty, Nothing, Nothing, Nothing)

This won’t work either, since the compiler cannot find the PropertyInfo of that property, it just doesn’t exist. You will get a NullReferenceException. You can only set it at runtime.

The solution is:

GetType(Excel.Chart).InvokeMember("ThePropertyYouWant", BindingFlags.SetProperty, Nothing, someChart, New Object() {someValue})

This way you just say to the runtime: set that value on that property, don’t try to read the metadata first!

Windows Azure SDK: connecting to non SQLExpress Instance

When you want to build an Azure application, but you don’t have SQL Express installed the build action in Visual Studio will fail.

You will receive the following message in your output window:

Windows Azure Tools: Failed to initialize the Development Storage service. Unable to start Development Storage. Failed to start Development Storage: the SQL Server instance ‘localhost\SQLExpress’ could not be found. Please configure the SQL Server instance for Development Storage using the ‘DSInit’ utility in the Windows Azure SDK.

To fix this you open the Windows Azure SDK Command Prompt:

Windows Azure SDK Command Prompt

And enter the following text:

dsinit /sqlinstance:.

dsinit /sqlinstance:.

This will cause Azure to use the default instance (with no name). You can switch this to whatever you like, just replace the . (dot) by the appropriate MS SQL instance.

The result will look like this:

Development Storage Initialization

Good luck, happy coding.

Debugging applications in virtual machines with VMware Workstation 7 and Visual Studio 2008 SP1

Can be a hassle, that’s why I’m writing this post for you:

First of all some prerequisites:

  • VMware Workstation 7 (6.5 probably will be the same)
  • A VM, XP / Vista / 7, whatever you want
  • Visual Studio 2008 SP1

Second of all: VMware can be a little cryptic with it’s error messages so stay calm!

We start by having our sample application we want to run on the VM:

<screenshot>

Next we click the wrench tool on the VMware toolbar in Visual Studio:

Click the wrench tool

This opens the following dialog:

Virtual Debugger Configuration Pages

For your convenience I highlighted the settings you need to change.

The following order is not the order in the window, but the order that seems the most understandable in my opinion:

Virtual Machine: The VM you want to debug into, just select a suitable vmx.

Remote Debug Monitor Path: The path to Remote Debugger folder on the host computer NOT on the guest! So for 32-bit debugging that would be:

C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\Remote Debugger\x86\msvsmon.exe

Replace x86 with x64 if you require 64-bit debugging.

Shared Folders: This one is not used

Guest Command: The command to be executed on the guest to start the application. This one was quite the hassle for me. If you leave it on the standard it will result in the following (cryptic) error:

A valid executable name has not been specified in Debugger settings. You can change this in Project > Properties > Debugging.

So instead of leaving it on default you enter this;

\\vmware-host\Shared Folders\test\application.exe

Please replace application.exe to the name of your executable!

The last item, Guest Logon Credentials, is the easiest. This should be the username and password you use to log in to the VM.

Next up is setting the shared folder between the guest and the host.

While I tried this with the Shared Folder Item in the window we just filled in, I just can’t seem to get it to work. So I bypassed this.

Go to the settings of the VM (in VMware Workstation –> VM –> Settings (CTRL+D)):

image 

On the second tab, you take shared folders, and click add (as pointed on the picture).

On the wizard I would suggest opening the shared folder in the debug folder of your application and name the shared folder ‘test’

image

Enable the share in the following window, and make it read-write.

Now we can start the debugging from Visual Studio. The application will then be started through the shared folder we just created.

Getting the DNS servers with .NET without WMI

Someone pointed me at System.Net.NetworkInformation, which has a lot of interesting objects.

You don’t have to use strings and query the WMI at runtime, which means you get compile time checking!

using System;
using System.Net;
using System.Net.NetworkInformation;

namespace WMITest
{
    internal class Program
    {
        public static int Main(string[] args)
        {
            NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
            foreach (NetworkInterface adapter in adapters)
            {
                IPInterfaceProperties properties = adapter.GetIPProperties();

                foreach (IPAddress dnsServer in properties.DnsAddresses)
                {
                    Console.WriteLine("{0} ", dnsServer);
                }

                Console.WriteLine("----------------------");
            }

            Console.ReadLine();
            return 0;
        }
    }
}

Hope it helps :)

Enabling Edit and Continue on 64-bit machines.

Ever had this error?

changes to 64-bit applications are not allowed

changes to 64-bit applications are not allowed

This occurs on 64-bit machines when trying to do Edit and Continue (a feature of the .NET CLR) on a 64-bit application.

It’s only available on 32-bit applications.

Now it’s up to the reader to determine if he needs a 64-bit application. 95% of the time the answer will be no.

So for those people I present the solution:

image

It’s quite simple. Go to properties, build and set the platform target to x86. And you’re ready to go Edit and Continue.

Please do read this about Edit and Continue.

SqlConnection, Close and deconstructor: Internal .Net Framework Data Provider error 1.

Today I experienced the following issue:

I had a class where I would open a SqlConnection, do some actions, and then in the deconstructor I closed the SqlConnection.

~Dumper()
{
    this._sqlConnection.Close();
}

Unfortunately every time my program ran it stopped with this error:

image

Internal .Net Framework Data Provider error 1.

(click to enlarge)

Well it seems that you cannot close a SqlConnection in a ~Deconstructor block.

So the solution is implementing the IDisposable interface

internal class Dumper : IDisposable
{
    private readonly SqlConnection _sqlConnection;

    public Dumper()
    {
        //build and open the connection
        this._sqlConnection = new SqlConnection(Settings.Default.ConnectionString);
        this._sqlConnection.Open();
    }

    /// <summary>
    /// Some function
    /// </summary>
    /// <param name="param">param</param>
    public void SomeFunction(SomeParameter param)
    {
    }

    public void Dispose()
    {
        this._sqlConnection.Close();
    }
}

And to use it you do this:

using (Dumper dumper = new Dumper())
{
    dumper.SomeFunction(myParam);
}

This will cause dumper to be Disposed after the } and it will no longer be available