Thursday, July 28, 2011

New App Hub Features Still Need Work

LeanBites200The July 18 Marketplace updates look like they still need some tweaking. I updated one of my apps and set the publish status to “hide” after certification. After app certification approval, for  some reason, it showed an update to the app on my phone (doesn’t seem hidden to me). I updated the app to the new version, and the splash screen was updated, but the icons were not updated and the application just showed a “My Application” header at the top of the page with no app content at all.

I thought maybe that was the result of the “Hide” status. So I un-hid the app in the marketplace. It didn’t prompt another update so I uninstalled the app from my phone. When I searched in the marketplace for my app to reinstall, it could not be found.

In order to reinstall the app, I had to navigate to my Lean Bites website on my phone and click the Zune Marketplace deep link in the right column of the website. After following that procedure, the app installed and is working correctly again with the new updated version.

I hope Microsoft gets these issues worked out before the consumer frustration gets to a new high and it doesn’t make my app look like it’s the problem. With so much riding on the new Windows Phone platform, it is unfortunate to see them stumbling over issues that probably should have surfaced in beta testing.

Friday, July 22, 2011

EF “Code-First” Table Mappings for Existing Database

Table MapIf you are using the MvcScaffolding package to scaffold the tables from an existing database and it throws an exception on the following line of the index.cshtml page. (The exception would show up in a different location on other data access pages).

@foreach (var item in Model) {

If the exception is of type System.Data.EntityCommandExecutionException where the inner exception is something to the effect of “Invalid object name ‘dbo.Ranks” where the actual database table name is the singular form like dbo.Rank, you probably need to explicitly define the table schema mappings in the OnModelCreating event of the context class because the existing database table names don’t match the default Entity Framework Convention over Configuration settings.


namespace LPM.Models
{
    public class LPMContext : DbContext
    {
        public DbSet<LPM.Status> Status { get; set; }
        public DbSet<LPM.Rank> Ranks { get; set; }
 
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Rank>().ToTable("Rank");
        }
    }
}

If you use SQL Profiler to trace the T-SQL statement issued by the application, you can see it was attempting to retrieve data from the [dbo].[Ranks] table which doesn’t exist. In my database it is [dbo].[Rank].

SELECT
[Extent1].[ID] AS [ID],
[Extent1].[RankNo] AS [RankNo],
[Extent1].[RankDescription] AS [RankDescription]
FROM [dbo].[Ranks] AS [Extent1]


This stumped me initially because the first table I used as a test was the “Status” table which by convention has the same name in the singular and plural form. So no exceptions where thrown and I could list, insert, update, and delete the records. After I updated the model from the database and added the Rank table, exceptions started flying until I added the modelBuilder.Entity<Rank>().ToTable(“Rank”) line in the OnModelCreating event.

Scott Guthrie’s Entity Framework 4 “Code-First”: Custom Database Schema Mapping has additional examples with more complex mapping scenarios.


photo credit: aaron13251 / CC BY 2.0

Thursday, July 21, 2011

MvcScaffolding uses SQL Express by Default

Where's WaldoThe fact that the MvcScaffolding package uses SQL Express by default can be both good and deceiving at the same time.

Using an Existing Database (not Code-First)

I used the package on a MVC3 project to scaffold the repository models and controllers for an existing SQL Server Standard database (not SQL Express) that had an existing Ado.Net Entity Framework model. The EF connection string obviously pointed to the existing database. However when running the application, the Index pages didn’t list any of the existing data from my database.

If this looks like the same problem you are having, feel free to skip to the bottom for the solution (convention over configuration).

Where’s the data?

I could add records, but they didn’t show up in the existing database. There was no Express database .mdf file in the application’s App_Data folder. There were no additional  connection strings (other than the EF connection to the existing database) in the web.config files or any of the dbcontext class files. I profiled the existing database with SQL Profiler and the existing database was completely untouched. I even added a <remove name=”LPMEntities” /> line before the EF connection string to make sure any default connection from the server root or machine.config was taken out of the inheritance tree (similar to what you would do for the aspnetdb membership database if you are using a full SQL Server instance).

The new data was being stored somewhere, but where? In a newly created SQL Express database.

How do I See the Data?

Open your SQL Server Management Studio (SSMS) or the version of SSMS for SQL Express. In the Object Explorer window, click Connect. Use .\sqlexpress as the server to connect to using Windows Authentication and voila the new mysterious “hidden” database.

SqlExpress MvcScaffolding package generated database

I hope this helps to clarify for other people attempting to use the MvcScaffoling in a Database-First scenario.

The Solution – Understand the Convention over Configuration

It took me a while to find a small subtle, yet crucial, detail in Scott Guthrie’s Using EF “Code First” with an Existing Database.

The following note is stated at the end of Step 5 – Configuring our Database Connection String:

EF “code first” uses a convention where context classes by default look for a connection-string that has the same name as the context class.  Because our context class is called “Northwind” it by default looks for a “Northwind” connection-string to use.  Above our Northwind connection-string is configured to use a local SQL Express database.  You can alternatively point it at a remote SQL Server.

In my case the Entity Framework connection string in the web.config was named “LPMEntities”. The class implementing the DbContext is named LPMContext as shown below.

namespace LPM.Models
{
    public class LPMContext : DbContext
    {
        public DbSet<LPM.Type> Types { get; set; }
        additional stuff here...
    }
}

Since LPMEntities is not the context class name, the EF generates a local SQL Express database.


I just added a connection string to the web.config with a name of LPMContext (same name as the context class) and my MVC forms are populated from the existing database.


Victory!



photo credit: Si1very / CC BY-SA 2.0

Friday, July 15, 2011

Error using MvcScaffolding with EF4.0

scaffoldingIf you are just starting out with the MvcScaffolding Nuget package to scaffold your basic CRUD operations on an MVC3 project, you should know that it requires EF 4.1 to run correctly without the following error.

The type 'LPM.Project' was not mapped. Check that the type has not been explicitly excluded by using the Ignore method or NotMappedAttribute data annotation. Verify that the type was defined as a class, is not primitive, nested or generic, and does not inherit from EntityObject

If you already ran the scaffolding via the Package Manager Console using syntax similar to the following, PM>scaffold controller <table> –Repository –Force, to resolve the error, I needed to:

  1. Delete the scaffolded controller files and view files from the project.
  2. Install the Entity Framework 4.1
  3. Re-Generate the Database From Model (assuming that is how you created the Entities to begin with)
  4. Right click on the .edmx Design surface, click Add Code Generation Item.
  5. Click the Code link in the Installed Templates tree. Select ADO.Net DbContext Generator. Name the code generation template, it ends with a .tt extension.
  6. Rebuild the project.
  7. Re-scaffold the tables.
  8. Run the project

Steps 4 & 5 above were the key to getting it to work after installing the Entity Framework 4.1 and with all my combinations of re-scaffolding, re-generating the model, re-creating the model, etc. That important bit of information came from MVC 3 Scaffolding issue with Entity Framework.

If you look at the Model.designer.cs (or .vb) code prior to adding the ADO.Net DbContext Generator, you will see that the Model entities do inherit from the EntityObject (which is noted in the error message as a potential cause of the exception). Adding the ADO.Net DbContext Generator disables the default code generation and inherits from the DbContext instead.

more information:

Friday, July 8, 2011

Physical to Virtual using SysInternals Disk2VHD

Virtual Prehistoric EraThe hard drive controller was regularly failing on my source control server. What to do? The server was due for an upgrade soon as its hardware was more or less obsolete and the performance was less than satisfactory. While the controller was still mostly working, I used SysInternals Disk2VHD to create a virtual copy of the physical server. In the interim while waiting on the new Hyper-V server to permanently place it on, I can temporarily run the server in VirtualPC 2007 and with three times more RAM than was available on the physical server.

The process was simple, fast, and seamless. I just had to re-activate the OS after the conversion. Just make sure you activate it before the expiration date which I believe was only 3 days on my copy or it will brick your ability to manage the server from the terminal.

While waiting for copying and converting processes to finish I ran across a few related posts that I thought I might want to reference in the future.

Wednesday, July 6, 2011

Database Primary Key Naming Conventions

Train couplingThis post specifically deals with the two naming conventions of a primary key for example “Id” or “<tablename>Id".

Using the convention including the tablename prepended to “Id” makes creating and reading SQL query joins more intuitively readable as in:

SELECT a.AuthorId
    , a.AuthorName
    , b.BookId
    , b.BookName 
FROM Author a
   INNER JOIN Book b 
   ON b.AuthorId = a.AuthorId

Versus the alternative using a standard key name, such as “Id" for all tables, as in the following:



SELECT a.Id AS AuthorId
    , a.AuthorName
    , b.Id AS BookId
    , b.BookName 
FROM Author a
   INNER JOIN Book b 
   ON b.AuthorId = a.Id

However it adds additional abstraction/mapping complexity when using a generic Repository pattern* that uses a standard primary key property name for the Repository base classes and interfaces.


*The design is possibly more correctly labeled as a DAO pattern depending on the specific implementation.


photo courtesy: amboo who? / CC BY-SA 2.0