Jim Rogers

Lives in Baton Rouge, LA, with two dogs, one cat, and one lovely wife. I'm a lead developer for GCR Incorporated.

Katrin and Jim

Month List

EF6 Configuration in a test project

by jim Jun 11, 2014 12:07 PM

I’ve upgraded to Entity Framework 6, and to avoid having to update the configuration files for all of the applications that use my data layer, I’m using the code option for configuration of the default provider.

This worked fine for my apps, but not for my test project, which gave me this error:

The default DbConfiguration instance was used by the Entity Framework before the 'ContextConfiguration' type was discovered. An instance of 'ContextConfiguration' must be set at application start before using any Entity Framework features or must be registered in the application's config file. See http://go.microsoft.com/fwlink/?LinkId=260883 for more information.

The solution was to explicitly initialize EF when the test project starts – with the help of the AssemblyInitilizeAttribute. ContextConfiguration is my subclass of DbConfiguration, which lives in the same project as my context classes.

[AssemblyInitialize]
public static void AssemblySetup(TestContext context)
{     DbConfiguration.SetConfiguration(new ContextConfiguration());
}

The test runners for Visual Studio and Resharper initialize in different ways, and one may work when the other doesn’t, for things like this. The above code works for both. without it, tests would pass in Resharper but not in Visual Studio, or on the build server.

Tags:

Enforcing platform configuration in a build event

by jim May 29, 2014 10:50 AM

We have a solution that is intended to be built with the x86 platform configuration selected. This is a per-user setting, and not the default, so I wanted to find a way to force other developers to have this selected.

My solution was to use a pre-build event in the data layer project (which is a dependency of most others and therefore built first.) If the platform name is incorrect, it simply returns 1 and fails the build.

The error message contains the full text of the build event, so the comment explaining what wrong should be pretty obvious to the person attempting to build. 

@if not '$(PlatformName)' == 'x86' (
    :: You should be building with the x86 platform selected in Configuration Manager
    exit /b 1
)
image 

Tags:

Date formatting gotcha

by jim Sep 21, 2013 2:12 PM

It’s common to see dates formatted with the format string {0:MM/dd/yyyy}.

I do not think that character means what you think it means! The forward slash character in a date format does not mean “forward slash.” It means “the default date separator.”

I discovered this little-known fact because I’m nerdy enough to have switched to a custom date format for my machine: yyyy.MM.dd.

image

This means that my custom date separator is now a period, not a slash, and so for that original format string I get unintelligible dates like 04.06.2013. And if you’re formatting dates on a web server, all your clients could be getting wacky dates…

The right way to write that format string is to escape your forward slashes with a backslash, like this: {0:MM\/dd\/yyyy}. That will give you the output you’re looking for on any system, regardless of the machine’s locale settings.

image

Or use ToShortDateString(), or the short date format specifier ‘d’, and specify the locale :-) 

Tags:

EF5 code first: same class, different database object

by jim Jun 20, 2013 8:54 PM

I’ve got an otherwise pretty standard Entity Framework setup, but this special requirement: getting data using my standard entities, but from a set of views rather than the actual tables. The views are in a separate schema, and reflect the old “published” – or “reference” – data, rather than the current data in my tables.

So let’s say I have a “Current” schema and a “Reference” schema.

So how to use one class to access the objects in both schemas? There are a number of options here; we could use a raw SQL query on our DbSet to pull Reference rows into our Current context. But then they are (by default) tracked in the Current context, which might get a bit weird – they would be updated into the Current context if I were to call SaveChanges().

Or I can use DbContext.Database.SqlQuery to map the Reference rows to my object – however, this doesn’t respect any column mapping that I might have in my classes, as SqlQuery (inexplicably) bypasses the mapping logic applied to DbSet entities.

The solution I settled on was to create a second context class, which re-maps the classes to the Reference schema.

public class ReferenceContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

            // Re-map the entities to the Reference views
            modelBuilder.Entity<Foo>().Map(m => m.ToTable("Foo", "Reference"));
            modelBuilder.Entity<Bar>().Map(m => m.ToTable("Bar", "Reference"));
        }


public DbSet<Foo> Foos { get; set; }

  

Tags:

jQuery Mobile - issues navigating to root

by Jim Apr 12, 2013 3:04 PM

When I load the default index.html page of my jQM site, I make an ajax call and dynamically show a couple of buttons. After navigating to a subpage, I can get back to the cached index.html by navigating to "index.html", either through a link or programmatically with $.mobile.changePage().

So far so good.

Now if I load the same site in IIS, without specifying the index.html: http://localhost/, I run into problems. "index.html" is not in the original url, so jQM thinks it's loading a new page. I retrieves the page from the server and inserts this into the DOM - but this time, without the dynamic content being created.

I've got a bunch of links to index.html, and I don't want to programmatically change each according to how the site is initially loaded. This hook into the pagebeforechange event will fix the url before navigation starts, and both use cases work seamlessly.

// hook into navigation to fix issue with blank root navigation vs. index.html
$(document).on("pagebeforechange", function (event, data) {

    // event is called twice, ignore the second object call
    if (typeof data.toPage == "string") {
        var target = data.toPage;

        // are we going to index, but that's not in the original path?
        if (target.toLowerCase().indexOf("index.html") > 0 &&
            location.href.toLowerCase().indexOf('index.html') == -1) {  

            // change to the root of the site instead of to index.html
            target = location.protocol + "//" + location.hostname + location.pathname;
            if (target.substr(target.length - 1, 1) != "/")
                target += "/";
            
            data.toPage = target;   // continue on with this new value
        }
    }
});

Tags:

Code