Setting up a local development environment with .NET and SQL Server
When you build line-of-business applications, the gap between a laptop prototype and a production database can swallow weeks of effort. A predictable local development environment removes that friction, especially when the stack leans on .NET for the application layer and SQL Server for persistence. Developers in Melbourne and Sydney frequently run hybrid stacks where backend services live in containers while a SQL Server instance sits on the host for predictable tooling support, and the same pattern translates well whether you are based in Brisbane, Perth, or a regional town in Tasmania.
This walkthrough focuses on practical choices: which SDK to install, which SQL Server edition fits a solo workstation, how to wire Entity Framework Core into the project, and how to keep the whole stack reproducible across teammates. It also touches on the small operational details that matter when your application is destined for clients whose data sits under the Privacy Act 1988 and the Notifiable Data Breaches scheme.
Installing the .NET SDK on your machine
Start with the SDK rather than the runtime, because the SDK ships the CLI, templates, and Roslyn compiler needed to scaffold and build projects. Download the installer from the official Microsoft site and pick the LTS channel if you want predictable support windows, or the current channel if you want access to the newest language features. On Windows, the installer adds dotnet to your PATH automatically; on macOS and Linux, prefer the dotnet-install script so you can pin a version per project with a global.json file.
After installation, confirm the toolchain by running dotnet --info in a fresh terminal. The output should list the active SDK, the runtime versions resolved, and any installed templates. If you work across multiple repositories that demand different SDK versions, global.json is your friend — it freezes the version for that folder tree so a teammate cloning on a Mac in Adelaide and another on Windows in Hobart both resolve the same toolchain. Keep the SDK up to date, but never upgrade casually in the middle of a sprint; pin first, validate on CI, and roll out once the green builds tell you it is safe.
Choosing and installing SQL Server locally
SQL Server Developer Edition remains the right default for local work: it is free, it includes every feature of Enterprise, and it permits production-style queries, indexing, and execution plans without a licence cost. Microsoft limits it to dev and test workloads, which is exactly what a workstation is for. Download the installer, choose the Basic install type, and accept the default instance name of SQLEXPRESS unless you have a reason to change it. During setup, record the sa password in your password manager rather than relying on Windows Authentication alone, because some EF Core tooling still needs SQL auth for things like dacpac deployments.
On macOS or Linux, SQL Server runs through Docker, and the mcr.microsoft.com/mssql/server image is the canonical choice. Pull the 2022 image, expose port 1433, and mount a volume for the data directory so your databases survive container restarts. Aussie teams often run Docker Desktop in Brisbane on Windows hosts and OrbStack or Colima on Macs, but the container behaves the same. Whichever route you take, run SELECT @@VERSION immediately after the first boot to confirm the instance is responding; a silent failure on startup is one of the more common causes of an afternoon lost to debugging.
Configuring your IDE for .NET and SQL
Visual Studio remains the most ergonomic IDE on Windows for full-stack .NET work because the SQL Server Object Explorer is built in and lets you browse tables, view execution plans, and profile queries without leaving the editor. If you prefer a cross-platform setup, Rider from JetBrains handles the .NET project side of the work cleanly and integrates with Azure Data Studio for database browsing. VS Code with the C# Dev Kit and the mssql extension is the lightweight alternative and a common option when the rest of the toolchain runs in WSL2. The focus is round-tripping between the editor and the database, so feel free to swap IDEs at this stage and benchmark what feels most productive.
Whichever editor you choose, install the SQL tools extension or companion app, set up a connection to your local instance, and create a sandbox database for ad-hoc query tuning. Many Australian developers stash their sandbox naming convention in a team README — something like $(initials)_$(feature)_local — so the database list stays greppable. Configure your editor to point at the local appsettings.Development.json when running, because that file should override any production connection strings stored elsewhere in the configuration tree.
Setting up Entity Framework and connection strings
Once the SDK and database are responding, scaffold the data layer. Run dotnet new webapi -n Blog.Web to start with a clean template, then add the EF Core packages your project actually needs: Microsoft.EntityFrameworkCore.SqlServer for the provider, Microsoft.EntityFrameworkCore.Design for the dotnet ef CLI, and Microsoft.EntityFrameworkCore.Tools if you want PMC-style commands. Open the project file and verify the package references resolve before going further, because a mis-matched transitive dependency will surface as a migration failure two hours later.
Wire the connection string into appsettings.json under a named section — ConnectionStrings:BlogDb is a reasonable convention — and bind it in Program.cs through builder.Services.AddDbContext<BlogContext>(options => options.UseSqlServer(connectionString)). For secret hygiene, swap the raw password for an environment variable or a user secret in development, and keep the connection string in appsettings.Development.json gitignored so a laptop left on a Sydney commuter train does not leak production credentials. When you want to layer in automated integration, such as the patterns explored on integration testing workflows, the same configuration shape carries through to the test project.
Seeding and running migrations against local data
With the DbContext registered, generate the first migration with dotnet ef migrations add InitialCreate. Inspect the scaffolded files before applying them, because EF Core will sometimes generate column types that do not match your domain — nvarchar(max) where you wanted a bounded string, or datetime2 where date reads better. Run dotnet ef database update to apply it to your local instance, then verify the tables through your SQL tooling. Repeat the cycle for each model change rather than editing migrations by hand once they have been applied to any shared environment.
For seed data, prefer a dedicated DbSeeder class invoked from Program.cs behind an environment check, because the alternative — running a SQL script after every migration — drifts fast. Seed deterministic IDs so tests can assert against known fixtures, and gate the seeder behind if (app.Environment.IsDevelopment()) so it never runs against a staging or production database. A common Aussie shop pattern is to include a handful of realistic seed rows in development to catch off-by-one pagination bugs that only surface with realistic data volumes.
Hardening your setup for reproducibility
The real test of a local environment is whether a new teammate can clone, run two commands, and reach a working database. Codify the steps in a setup.sh or setup.ps1 script that installs the SDK, restores packages, applies migrations, and seeds data. Commit a .editorconfig, a global.json, and a Directory.Build.props so style, SDK version, and common package versions are enforced before anyone types dotnet build. Use a docker-compose.yml to bring up SQL Server for Linux and macOS teammates, and document the Windows-native path separately rather than assuming everyone uses the same OS.
Finally, decide on a backup policy for local databases. Even a daily solo db export to an external drive prevents the kind of data loss that ends a sprint. If your work touches personal information, even in development, scrub the seeded data so it does not resemble a real Australian customer under the Privacy Act — synthetic identities, fake postcodes, and clearly fictional suburbs keep you on the right side of the Notifiable Data Breaches scheme even if the laptop walks out the door.
Reliable setup checklist
- Pin the .NET SDK version in
global.jsonand update it on a deliberate cadence rather than ad hoc. - Use SQL Server Developer Edition on Windows or the official Docker image elsewhere, and persist data with a mounted volume.
- Store the local password in a user secret or environment variable, never in
appsettings.json. - Run
dotnet ef database updateas part of setup so a fresh clone ends at a working schema. - Commit a
setupscript and adocker-compose.ymlso a new teammate reaches a green build on day one. - Back up local databases on a schedule, even if the only consumer is your own debugging session.
- Audit seed data for personal information and replace it with synthetic records before sharing screenshots or schema dumps.
Now run dotnet ef database update, open the API in your browser, and confirm the health endpoint returns 200 — that single green response is the most reliable signal that your local development environment is ready for real work.