Category Archives: Visual Studio

Getting Entity Framework to recognise the return type of a Stored Procedure that returns a #temp table

The Situation

I recently wanted to declare a table, insert data into it and then, depending on a variable passed in to the stored procedure (@i_bitCurrent), either return the contents of the table, or filter the contents with a Where clause and return them (3 options in total). The reason I wanted to use the temporary table approach was to avoid duplicating the long select statement 3 times, with just the Where part of the statement being different (or have three separate stored procedures).

The Problem

I got the stored procedure to work, and return the expected data set when run from within Microsoft SQL Management Studio, but Entity Framework (in Visual Studio 2012) refused to recognise the return type (it saw a return type of nullable int).

The Solution

After Googling the problem I found a similar problem and suggested answer on Stack Overflow – I needed to supply a faux data contract that Entity Framework would then use as the return type. The faux data contract is the first IF statement in the code below.

The Code

This is a cut-down version of the code, so you can see why I did not want to duplicate it (making changes would ahve been a nightmare…) The faux data contract IF statement at the beginning will never be executed as 1 will never equal 2. It is simply there to get Entity Framework to recognise the return type. It will need to be updated if the temporary table is ever updated.

IF 1 = 2
  BEGIN
    SELECT
    cast(null as int) as UserId
    ,cast(null as nvarchar(250)) as Username
    ,cast(null as int) as RoleCount
    ,cast(null as datetime) as UserRevoked
    ,cast(null as bit) as Locked
    ,cast(null as bit) as ForcePassChange
    ,cast(null as varchar(200)) as ClientName
    WHERE
    1 = 2 
  END

CREATE table #tmpResults (
   UserId int, 
   Username nvarchar(250), 
   RoleCount int, 
   UserRevoked datetime, 
   Locked bit, 
   ForcePassChange bit, 
   ClientName varchar(200)
)

INSERT #tmpResults (
   UserId,
   Username,
   RoleCount,
   UserRevoked,
   Locked,
   ForcePassChange,
   ClientName
)
SELECT
   u.UserId,
   u.Username,
   (SELECT COUNT(*) 
      FROM USERROLE 
      WHERE FKUserId = u.UserId AND Revoked IS NULL),
   u.Revoked,
   u.Locked,
   u.ForcePassChange,
   c.Name
FROM [USER] u LEFT OUTER JOIN [CLIENTS].[dbo].[CLIENT] c on u.FkClientId = c.ID
ORDER BY u.UserId

IF(@i_bitCurrent IS NULL)
  BEGIN
     SELECT * FROM #tmpResults
  END
IF(@i_bitCurrent = 1)
  BEGIN
     SELECT * FROM #tmpResults
     WHERE (UserRevoked IS NULL OR UserRevoked > GetDate())
     ORDER BY UserId
  END
IF(@i_bitCurrent = 0)
  BEGIN
     SELECT * FROM #tmpResults
     WHERE (UserRevoked IS NOT NULL AND UserRevoked < GetDate())
     ORDER BY UserId
  END

Entity Framework / Visual Studio

Then when I removed the stored procedure from the model in Visual Studio (from both the Stored Procedures / Functions folder and Function Imports folder), and refreshed the model from the database, the stored procedure was added correctly and a Complex Type created with the correct return value.

That is an Entity Framework Hack!

Note

Ints and bits (bools) will be returned as nullable, so you may need to use returnType.fieldName.Value ( in C#, or the equivalent in the language you are using) to access the value of these types in the returned type.

Tagged , , , , , , , , , , ,

Config Transform Files for changing Web.config for release (ASP.Net 4.0)

You can change parts of the web.config between different builds (e.g. debug and release). I used it to change whether cookies must only be sent and received over ssl.
It is also useful for changing connection strings from debug to live versions and also user defined keys (examples below).

Clicking the arrow next to Web.config (in the Solution Explorer Visual Studio)  reveals the various transform files. If you have added more build types you can add more transform files by right clicking on Web.config and selecting Add Config Transform.

Examples

Double-click a transform file to open it and see what it is doing. It has some examples, but the syntax I required for the httpcookies element was a different to these.

Remove debug attribute

System.web already contained one transform, which removes the debug attribute from the compilation element within the system.web element.

Web.Release.Config

<system.web>
    <compilation xdt:Transform="RemoveAttributes(debug)" />
</system.web>

Debug

<system.web>
    <compilation debug="true" targetFramework="4.0">
        ...
    </compilation>
    ...
</system.web>

Release

<system.web>
    <compilation targetFramework="4.0">
        ...
    </compilation>
    ...
</system.web>

Require cookies to be transmitted and requested only over a secure connection

I added another transform which changes the value of a named attribute (requireSSL) in a named element (httpCookies) within the system.web element.

Web.Release.Config

<system.web>
    ...
    <httpCookies requireSSL="true" xdt:Transform="SetAttributes(requireSSL)" />
</system.web>

Debug

<system.web>
    <httpCookies requireSSL="false" />
    ...
</system.web>

Release

<system.web>
    <httpCookies requireSSL="true" />
    ...
</system.web>

Change the value of a defined key

I also added another transform which changes the value attribute of an add element by matching the key attribute (live) within the appSettings element.

Web.Release.Config

<appSettings>
    <add key="live" value="true" xdt:Locator="Match(key)" xdt:Transform="SetAttributes(value)" />
</appSettings>

Debug

<appSettings>
    ...
    <add key="live" value="false" />
</appSettings>

Release

<appSettings>
    ...
    <add key="live" value="true" />
</appSettings>

Changing a connection string

I did not need this myself but the following changes the connectionString attribute of an add element (within the connectionStrings element) by matching the name attribute (MyDB) and changes the value of the connectionString attribute to ReleaseSQLServer. Note that the attribute name (connectionString) does not need to be specified. You can change multiple attributes this way, by specifying each attribute and its new value (e.g. including providerName=”value” in the add element below).

Web.Release.Config

<connectionStrings>
    <add name="MyDB" connectionString="ReleaseSQLServer" xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>

Debug

<connectionStrings>
    <add name="MyDB" connectionString="DebugSQLServer" providerName="System.Data.EntityClient" />
</connectionStrings>

Release

<connectionStrings>
    <add name="MyDB" connectionString="ReleaseSQLServer" providerName="System.Data.EntityClient" />
</connectionStrings>

Conclusion

Config transform files seem a very useful tool when using Visual Studio to publish your projects, and not using your own build scripts.

More useful information

Dan Maharry’s explanation of config transform files
MSDN Article on config transform files

Tagged , , , , , , ,

Fixed: Error when deploying a .Net 4.0 project (that was downgraded from .Net 4.5) to a .Net 4.0 server

I recently had to downgrade a .Net 4.5 project to .Net 4.0 so that it could run on MS Server 2003. I had many warnings and errors which I managed to clear up, as detailed in my previous post Downgrading an MVC4 project from .Net 4.5 to .Net 4.0, and the project built (hurrah!). Then I deployed it to the 2003 server and received the following error:

Could not load type 'System.Runtime.CompilerServices.ExtensionAttribute' from assembly 'mscorlib, Version=4.0.0.0, 
Culture=neutral, PublicKeyToken=b77a5c561934e089'.

Research

Googling this error did not show anything useful as others seemed to be having problems going from .Net 4.0 to .Net 4.5 (the solution for most people seemed to be to install .Net 4.5 on their server, but this was not an option for me as my server is running MS Server 2003), but this did give me the clue that it probably was a .Net version problem..

I used JustDecompile (a free program by Telerik) to look at all the dlls in my bin directory (of the published project) and low and behold there were a few that were still compiled against .Net 4.5.

Now to get these DLLs to target .Net 4.0…

First I looked at NuGet Package Manager thinking I could uninstall and reinstall the affected packages, but the fact that they all had various dependencies on each other meant this was not practicable.

Luckily my next endeavour turned out to be the answer. I looked at packages.config in my project root folder (same folder as the .csproj file) and opened it in a text editor (Notepad++ is my preference). Look at all those 45 references!

This is what is looked like:

<?xml version="1.0" encoding="utf-8"?>
<packages>
     <package id="DotNetOpenAuth.AspNet" version="4.3.0.13117" targetFramework="net45" />
     ...various other packages, most trageting 40 and some 45...
</packages>

So I just changed all the net45 references to net40, saved the file and rebuilt my project.

<?xml version="1.0" encoding="utf-8"?>
<packages>
     <package id="DotNetOpenAuth.AspNet" version="4.3.0.13117" targetFramework="net40" />
     ...etc...
</packages>

Looking at the offending DLLs in the bin directory, with JustDecompile, confirmed that they were now targeting .Net 4.0 (Hurrah!).

And now it runs on my 2003 server 🙂

Tagged , , , , , , , ,

Downgrading an MVC4 project from .Net 4.5 to .Net 4.0

I recently created a new project in Visual Studio 2012 and didn’t really think much about the .Net version (mistake!). It turns out that the server it is destined for is still MS Server 2003, which will not run .Net 4.5. Oh dear.

So I Googled downgrading, and the process of changing the target framework from 4.5 to 4.0 is very simple, just a couple of clicks, but getting the project to build after that can be a major headache!

Changing the target framework:

  1. Right click on the project in the Solution Explorer (in Visual Studio) and select Properties.
  2. Change the Target Framework drop-down to whatever framework you now wish to target.
  3. Do the same for any other projects or test projects in the solution, that you also wish to change the target framework for.

Note: Make sure you do not select .Net Framework x Client Profile. This seems to have caused others problems.

Getting the damn project to build again…

This is where my headaches began. I only got a couple of errors when building, but they took me a long time to fix. There were also many warnings about dependencies between my references.

Reference Dependency Warnings

To solve these warnings I have to manually edit my .csproj file in a text editor. This MSDN article about Troubleshooting .NET Framework Targeting Errors suggests replacing references with the simple form. I tried this, but it did not seem to make a difference. I also discovered that editing the .csproj file can cause the project to not load in Visual Studio. It would tell me the line with the error (which was the line after the edit I had made) and I fixed it by copying one of the other references over the edit I had made, and then changing the reference name back to what I wanted it to be. This got rid of any characters VS was not expecting.

I then noticed that some of my references still had ‘net45’ in their paths, as in the example below. Correcting this to ‘net40’ fixed many errors, and if you look in the file structure of your project you should see that there is a 45 and a 40 folder.

<Reference Include="Microsoft.Data.OData, Version=5.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
     <SpecificVersion>False</SpecificVersion>
     <HintPath>..\packages\Microsoft.Data.OData.5.5.0\lib\net40\Microsoft.Data.OData.dll</HintPath>
</Reference>

Reference Errors

But I still had one big error: System.Web.Http was not behaving itself and believed it relied on another reference (I belive Newtonsoft.Json) that was .Net 4.5. I tried many things, including removing and re-adding the reference to System.Web.Http, and even removing all references to System.Web.* and re-adding them; still the same error. I also tried similar things with Newtonsoft.Json. Eventually the solution took fairly little work on my part, and here it is:

How I fixed System.Web.Http

  1. In visual Studio, click the Tools menu and select Library Package Manager > Manage NuGet Packages for Solution
  2. Click on Updates
  3. Update all Microsoft packages (I also updated JQuery, etc, but this shouldn’t be necessary if you don’t want to do this)
  4. Click Restart Now.
  5. Rebuild project.

My project now build without any errors 🙂

One further problem…

My project built, but when I ran it and tried to access the database I received an Entity Framework error, it had failed to load.

Solution:

  1. Open Nuget Package Manager (Tools > Library Package Manager > Manage NuGet Packages for Solution) and locate Entity Framework in the list of installed packages.
  2. Click the Manage button next to Entity Framework.
  3. Un-tick the boxes next to your project(s) that are using Entity Framework (this will uninstall Entity Framework)
  4. Click on Online and use the search box in the top right to search for ‘entity’.
  5. Click on the Entity Framework package and then the Install button. The correct version for your .Net framework should download.
  6. Click the Restart Now button.
  7. Build and run your project to test.

Are you still having problems?

If your project still contains reference errors then you may need to use the Package Manager Console (Tools > Library Package Manager > Package Manager Console) to uninstall and reinstall the related packages. This was one of the things I tried before I remembered that the NuGet package manager would probably be easier. One problem I ran into was that you cannot uninstall a package that is relied upon by another package, so you may end up uninstalling and reinstalling a lot more packages than you really need to.

Conclusion

It seems that downgrading a project can be simple, but finding the solution can take a long time. If Visual Studio had a tool to help with this (especially upgrading a project) I think it would save a lot of programming hours.

Edit: I had a further problem with my application causing an error when it was deployed to the server. Here’s how I fixed it: Error when deploying a .Net 4.0 project (that was downgraded from .Net 4.5) to a .Net 4.0 server.

If you have had to downgrade a project in Visual Studio and have any more tips, tricks or links to helpful resources (or even questions) please leave a comment.

Tagged , , , , , , , , ,