All posts by Julie Lerman

EF Core’s IsConfigured and Logging

I got a little confused about some behavior today and finally realized my mistake so thought I would share it. This mostly happens in demo apps that I’m building that are not using  ASP.NET Core.

In these cases, I typically stick the DbContext provider configuration in the OnModelConfiguring method. For example, if I’m using SQLite, then I would specify that in the method as such:

protected override void OnConfiguring
 (DbContextOptionsBuilder optionsBuilder)
{
   optionsBuilder.UseSqlite (@"Filename=Data/PubsTracker.db");
}

I also have been using the logging factory a lot. After defining it, I also configure it. I hadn’t thought much about where I was placig it so added it in randomly.

protected override void OnConfiguring 
  (DbContextOptionsBuilder optionsBuilder)
{
  optionsBuilder.UseLoggerFactory (MyConsoleLoggerFactory);
  optionsBuilder.UseSqlite (@"Filename=Data/PubsTracker.db");
}

Then I added in some tests to had to avoid the SQLite provider if the InMemory provider was already configured, so I wrapped the UseSqlite method with a check to see if the options builder was already configured.

protected override void OnConfiguring
  (DbContextOptionsBuilder optionsBuilder)
{
  optionsBuilder.UseLoggerFactory (MyConsoleLoggerFactory);
  if(!optionsBuilder.IsConfigured)
  {
    optionsBuilder.UseSqlite (@"Filename=Data/PubsTracker.db");
  }
}

But my logic wasn’t working. I was running some migrations but they were suddenly not recognizing the UseSqlite method. I’ve used this pattern so many times. It took me a while to realize what was going on. The UseLoggerFactory is a configuration!

I just had to move the UseLoggerFactory logic after the IsConfigured check and all was well.

This is one of those dumb things that seems so silly you wouldn’t imagine someone else would make such a mistake. But since it bit me, I thought it was worth sharing mostly for the sake of the next coder who is trying to solve the same problem.

The Secret to Running EF Core 2.0 Migrations from a NET Core or NET Standard Class Library

I have had two people that watched my Pluralsight EF Core Getting Started course (which will soon be joined by an EF Core 2: Getting Started course) ask the same question, which mystified me at first.

The were running migrations commands which caused the project to compile, but the commands did not do anything. For example, add-migration didn’t add a migration file. get-dbcontext did not return any information. The most curious part was there was no error message! I was able to duplicate the problem.

With EF6 it was possible to use migrations from a class library with no exe project in sight. EF Core migrations can run from a .NET Framework or .NET Core project but not .NET Standard. It needs a runtime. A common workaround is that even if you haven’t gotten to the UI part of your app yet, to just add a .NET Core console app project to the solution, add the EF Core Design Nuget package to it and set it as the startup project. But it’s still possible to do this without adding in a dummy project.

We already knew about the multi-targetting fix which solved an error when you try to run migrations from a .NET Standard library. But even with that fix in place, we were getting the mysterious nothingness.

The answer to the question was buried in a GitHub issue and in comments for the Migrations document in the EF Core docs. This same solution solved a problem I was having when trying to use migrations in a UWP app (again, not .NET Core or .NET Framework) that used a separate class library to host its DbContext.

I’m writing this blog post to surface the solution until it is resolved.

The solution that we used with EF Core 1.0 in order to run migrations from a .NET Standard library was to multi-target for .Net Standard (so you can use the library in a few places) and .NET Core (so you can run migrations).

That means replacing

<PropertyGroup>       
  <TargetFramework>netstandard20</TargetFramework>
</PropertyGroup>

with

<PropertyGroup> 
  <TargetFrameworks>netcoreapp2.0;netstandard2.0</TargetFrameworks>
</PropertyGroup>

Notice that the attribute name is now plural and there is a semi-colon between the two SDKs.

But there’s one more secret which is not in the documentation.

For .NET Standard 2.0 (and EF Core 2.0), you also need to add the following to csproj.

<PropertyGroup>
 <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles></PropertyGroup>

Now with the DbContext project set as the startup and ensuring that the package manager console (or command line) are pointing to the same project, your migration commands will work.

Thanks to Christopher Moffat who found the solution in the GitHub issues and shared it in the comments on the EF Core Package Manager Console Tools document.


Screenshot for Tony ..see my comment in reply to your comment below.

Domain-Driven Design Europe 2018 in Amsterdam

I’m excited to be attending and speaking at DDD Europe 2018 in Amsterdam on Feb 1-2 2018. It’s an honor to be on the speaker roster with so many DDD gurus and other people with amazing DDD experiences stories to share.

The lowest early-bird ticket prices can still be bought through Nov 30 at €599 (+21% VAT =  €724 (app. ~$860US +). The ticket will go to €699 (+VAT) from Dec 1-Dec31 and then to €749 (+VAT) until the conference.

Prior to the conference,  there are also 10 amazing workshops ranging from 1/2 day to 2 days across January 30 – 31st.

I’ll be doing a 2  hour workshop during the conference proper on using EF Core 2 to map DDD patterns in your domain. It will be a hands-on workshop and my intention is to build some koans for attendees to work with. Although the flavor of hands-on may shift as I continue to percolate ideas.

Watch my Domain-Driven Design Fundamentals course on Pluralsight

Next Up: Devintersection, Las Vegas Oct 30-Nov 2

I have been away from home more than at home this fall! I have two trips behind me:

Trip 1: London for ProgNet, Salt Lake City for Pluralsight Live and Denver for Explore DDD.

Trip 2: Orlando for AngularMix then a side trip to Miami to visit friends and relatives

I’m home again for a bit then off again to Las Vegas for Devintersection. If you are still thinking about going (you should, really) you can still get a small discount using the code “LERMAN” when you register.

I will be giving 3 talks, participating in a panel and of course attending talks.

One for SURE that I’ll attend is on EF Core by two members of the team (and my friends!) Diego Vega and Andrew Peters on Tuesday.

I’m also doing an EF Core 2 talk which will be complementary to their session (not redundant) . That talk is on Wednesday morning.

 

Later on Wednesday I’m doing a session (should be FUN) for developers to take advantage of SQL Server in containers for quick dev environments. There I will show setting up and using a docker container with SQL Server for Linux (on my mac) and then a windows container for SQL Server Developer. For a dev or testing environment these are such fast and easy ways to spin up a SQL Server.

In my last session, which is on Thursday, I’m going to mostly code (yay! What is more fun that that?) to build up a data api and provide some design guidance at the same time as letting you get MORE eyeballs full of EF Core 2.0. And for a bonus, I finally got my hands on Azure Functions so I get to show off what I built on there as well.

After that, I’ll be on the closing panel. One NEVER knows what to expect there. Should be fun.

And also how cool is this graphic that the conference created, just for me to share just with you! 

 

 

 

 

New Pluralsight Course: Interacting with SQL Server data in Visual Studio Code on Win, Mac, Linux

imageMy latest course on Pluralsight, Cross-platform SQL Server Management for Developers using VS Code, went live earlier this month (just as I was about to hop on a plane for 2 weeks of conference travel!)

This is a course on a Visual Studio Code extension that I enjoy using so much that I wanted to share it with you. It is the mssql extension which lets you interact with SQL Server in a fairly rich way that belies the lightness of the IDE which it extends. Because VS Code is cross-platform, so are all of its extensions. So you can use this while you are coding on Windows, Mac or Linux and want to do some basic interaction with a SQL Server database.

As SQL Server examples, I used SQL Server LocalDb on Windows, SQL Server for Linux in a Docker container on a Mac and Azure SQL in the cloud. The course starts not only y showing you how to install VS Code (and some VS Code basics) and the extension but also by walking you through how to set up each of the database servers. That means it also has a lesson on Docker , installing and running an image as well as a quick start on creating a new SQL database in the Azure portal.

Once everything is set up, I dig through the features and functionality of the mssql extension. And I turned over ever possible stone to make sure you don’t miss helpful features which is the norm if you just start using such a tool without any preparation.

The course is mostly demos and very light on Powerpoint slides and I do work in Windows, on my Macbook and even in a Linux virtual machine.

imageWhat I’m also proud about this course is that if you’ve never used VS Code before, you’ll learn how to get around this amazing editor. If you’ve never used Docker before, I provide a really helpful and gentle introduction and you’ll be able to work with it. I had some great support from the team responsible for this extension as they were so happy to have this kind of attention paid to it.

So whatever language you code in, whatever O/S you work on, if you are using SQL Server (or interested in using it), this course should be a great help in mastering this very handy extension!

Below is the Table of Contents for the course.

If you need a 30-day free trial to the Pluralsight library so that you can watch this, send me a note!


Module 1: Introducing and Installing VS Code and the mssql Extension

In this module you’ll get a short introduction to the cross-platform and free developer IDE, Visual Studio Code and its mssql extension, The extension allow you to perform some key interactions with a SQL Server database without leaving the IDE. You’ll also walk through installing both the IDE and the extension on Windows and macOS

  • Module and Course Overview
  • Introducing Visual Studio Code and the mssql Extension
  • Installing Visual Studio Code on Windows
  • Installing Visual Studio Code on macOS
  • Introducing Visual Studio Code’s Coding Super Powers
  • Installing the mssql Extension in VS Code

 

 

Module 2: Preparing SQL Server for Any Platform, Locally and in the Cloud

In this module, you’ll learn how to set up a variety of SQL Servers. All of them are quick to install. You’ll learn to install SQL Server LocalDb on Windows, create an Azure SQL Database in the cloud and use a Docker image of SQL Server for Linux to quickly spin up SQL Server in a container on macOS. This will ensure that you have a SQL Server database to interact with in the rest of the course.

  • SQL Server LocalDB: The Simplest SQL Server
  • Setting Up an Azure SQL Database in the Cloud
  • Verifying the New Azure SQL Database
  • Setting Up the Last Details of Your Azure SQL Database
  • Using a Docker Container to Host SQL Server for Linux on Any O/S
  • Installing Docker and Getting the SQL Server Container Running
  • Verifying the Containerized Database
  • Understanding Persistence and Lack of Persistence in Containers
  • Pulling a Custom Image with the Sample Database in Place

 

Module 3: Connecting to the Various SQL Servers From Various Platforms

In this module, you’ll learn the ins and outs of connecting to a variety of local, cloud and containerized SQL Servers with the mssql extension. You’ll learn how to use the commands and shortcuts, how connection profiles and passwords are stored and even how to create a handy shortcut for getting mssql started.

  • mssql’s Commands and Execution Engine
  • Connecting to LocalDB While Learning More About mssql Connections
  • Connecting to Azure SQL from Windows and macOS
  • Demonstrating How mssql Securely Stores Your Passwords
  • Using ADO.NET Connection Strings to Connect
  • Connecting to the Database in the Docker Container
  • Connection Keyboard and Status Bar Shortcuts
  • Creating a Keyboard Shortcut to Start up mssql and Connect

Module 4 : Learning the mssql Basics to Connect, Query and Create

In this module you’ll start interacting with the database, executing queries and commands, and exploring  result sets. You’ll learn about the snippets and also learn about attaching to existing database files and creating new databases from scratch. Most importantly  you’ll learn about the great SQL editor and result view support that the mssql extension brings to you.

  • Attaching an Existing Database File
  • Interacting with the Results of Your First Query
  • The Intelligent Editor Window
  • Using Snippets to Speed Up Command Building
  • Exploring Multiple Result Sets Further
  • Using Snippets to See Database Metadata
  • Creating Databases, Tables and Data

Module 5: Leveraging Advanced Tips & Tricks

This module will dig deeper into mssql and provide tips that take advantage not just of mssql features, but also capabilities of Visual Studio Code to make using mssql easier.

  • Exporting Results to CSV, JSON or Excel
  • Localization of mssql’s Messages
  • Controlling Behavior Through VS Code’s Settings
  • Formatting Code in the Editor Window
  • Results Window Tricks, Shortcuts & Settings
  • Checking Out the Last Few Settings
  • Creating Your Own SQL Snippets in VS Code
  • Looking Ahead to Integrated Authentication on Mac and Linux

What’s in that sqlservr.sh file on the mssql-sqlserver-linux docker image anyway?

Update June 3, 2017: The team has revised the docker image and the bash file is gone, presumably with its logic broken up in to various locations. Still I’m glad I grabbed this when I did to satisfy my curiosity!

Microsoft has created 4 official Docker images for SQL Server: SQL Server for Linux, SQL Server Developer Edition, SQL Server Express and (windows) SQL Server vNext) . They can be found on the Docker hub (e.g. https://hub.docker.com/r/microsoft/mssql-server-linux/) and there is also a Github repository for them at github.com/Microsoft/mssql-docker. Some of the files that go along with that image are not on Github. The Dockerfile files for each image run some type of startup script. The Windows images have a PowerShell script called start.ps1. You can see those in the Github repo. The Linux image runs a bash file called sqlservr.sh. That’s not included in the repo though and I was curious what it did.

Note: I wrote a blog post about using the SQL Server for Linux container (Mashup: SQL Server on Linux in Docker on a Mac with Visual Studio Code and I’m also writing an article about using the containers for my July MSDN Magazine Data Points column (watch this space).

Still a bit of a bash noob, I learned how to read a file from a docker container on ..you guessed it…StackOverflow.  Following those instructions, I created a snapshot of my running container

MySqlServerLinuImage git:(master) docker commit juliesqllinux  mysnapshot

sha256:9b552a1e24df7652af0c6c265ae5e2d7cb7832586c431d4b480c30663ab713f0

and ran the snapshot with bash:

  MySqlServerLinuImage git:(master) docker run -t -i mysnapshot bin/bash

[email protected]:/# 

Then at the new prompt (#), used ls to get the listing

[email protected]:/# ls

SqlCmdScript.sql  SqlCmdStartup.sh  bin  boot  dev  entrypoint.sh  etc  home  install.sh  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

then navigated to  folder where the bash file is and listed its contents:

[email protected]:/opt/mssql/bin# ls

compress-dump.sh  generate-core.sh  mssql-conf  paldumper  sqlpackage  sqlservr  sqlservr.sh

Once I was there I used the cat command to list out the contents of the sqlservr.sh file and see what it does. Here is the secret sauce in case, like me, you NEED to know what’s going on under the covers!

[email protected]:/opt/mssql/bin# cat sqlservr.sh 

#!/bin/bash

#

# Microsoft(R) SQL Server(R) launch script for Docker

#

ACCEPT_EULA=${ACCEPT_EULA:-}

SA_PASSWORD=${SA_PASSWORD:-}

#COLLATION=${COLLATION:-SQL_Latin1_General_CP1_CI_AS}

have_sa_password=""

#have_collation=""

sqlservr_setup_prefix=""

configure=""

reconfigure=""

# Check system memory

#

let system_memory="$(awk '/MemTotal/ {print $2}' /proc/meminfo) / 1024"

if [ $system_memory -lt 3250 ]; then

    echo "ERROR: This machine must have at least 3.25 gigabytes of memory to install Microsoft(R) SQL Server(R)."

    exit 1

fi

# Create system directories

#

mkdir -p /var/opt/mssql/data

mkdir -p /var/opt/mssql/etc

mkdir -p /var/opt/mssql/log

# Check the EULA

#

if [ "$ACCEPT_EULA" != "Y" ] && [ "$ACCEPT_EULA" != "y" ]; then

 echo "ERROR: You must accept the End User License Agreement before this container" > /dev/stderr

 echo "can start. The End User License Agreement can be found at " > /dev/stderr

 echo "http://go.microsoft.com/fwlink/?LinkId=746388." > /dev/stderr

 echo ""

 echo "Set the environment variable ACCEPT_EULA to 'Y' if you accept the agreement." > /dev/stderr

 exit 1

fi

# Configure SQL engine

#

if [ ! -f /var/opt/mssql/data/master.mdf ]; then

 configure=1

 if [ ! -z "$SA_PASSWORD" ] || [ -f /var/opt/mssql/etc/sa_password ]; then

 have_sa_password=1

 fi

# if [ ! -z "$COLLATION" ] || [ -f /var/opt/mssql/etc/collation ]; then

# have_collation=1

# fi

 if [ -z "$have_sa_password" ]; then

        echo "ERROR: The system administrator password is not configured. You can set the" > /dev/stderr

        echo "password via environment variable (SA_PASSWORD) or configuration file" > /dev/stderr

        echo "(/var/opt/mssql/etc/sa_password)." > /dev/stderr

 exit 1

 fi

fi

# If user wants to reconfigure, set reconfigure flag

#

if [ -f /var/opt/mssql/etc/reconfigure ]; then

 reconfigure=1

fi

# If we need to configure or reconfigure, run through configuration

# logic

#

if [ "$configure" == "1" ] || [ "$reconfigure" == "1" ]; then

 sqlservr_setup_options=""

# if [ -f /var/opt/mssql/etc/collation ]; then

# sqlservr_setup_options+="-q $(cat /var/opt/mssql/etc/collation)"

# else

# if [ ! -z "$COLLATION" ]; then

# sqlservr_setup_options+="-q $COLLATION "

# fi

# fi

 set +e

 cd /var/opt/mssql

 echo 'Configuring Microsoft(R) SQL Server(R)...'

 if [ -f /var/opt/mssql/etc/sa_password ]; then

 SQLSERVR_SA_PASSWORD_FILE=/var/opt/mssql/etc/sa_password /opt/mssql/bin/sqlservr --setup $sqlservr_setup_options 2>&1 > /var/opt/mssql/log/setup-$(date +%Y%m%d-%H%M%S).log

 elif [ ! -z "$SA_PASSWORD" ]; then

 SQLSERVR_SA_PASSWORD_FILE=<(echo -n "$SA_PASSWORD") /opt/mssql/bin/sqlservr --setup $sqlservr_setup_options 2>&1 > /var/opt/mssql/log/setup-$(date +%Y%m%d-%H%M%S).log

 else

 if [ ! -z '$sqlservr_setup_options' ]; then

 /opt/mssql/bin/sqlservr --setup $sqlservr_setup_options 2>&1 > /var/opt/mssql/log/setup-$(date +%Y%m%d-%H%M%S).log

 fi

 fi

 retcode=$?

 if [ $retcode != 0 ]; then

 echo "Microsoft(R) SQL Server(R) setup failed with error code $retcode. Please check the setup log in /var/opt/mssql/log for more information." > /dev/stderr

 exit 1

 fi

 set -e

 rm -f /var/opt/mssql/etc/reconfigure

 rm -f /var/opt/mssql/etc/sa_password

 echo "Configuration complete."

fi

# Start SQL Server

#

exec /opt/mssql/bin/sqlservr $*