Welcome to the twenty-second episode of my course “Becoming a software developer” in which we will use SQL Server database along with Entity Framework Core library.
All of the materials including videos and sample projects can be downloaded from here.
The source code repository is being hosted on GitHub.
Scope
- SQL Server
- Entity Framework Core
Abstract
SQL Server
At first, we need to have access to the SQL Server where we could store our data. You can download SQL Server here and install it on your own or just connect to the instance running somewhere in the cloud or locally by using Docker like I did.
Once the SQL Server is installed, there are many tools that provide a graphical interface for managing the database.
One of the most popular ones (and also free) is SSMS, yet there are also others such Datagrip, Team SQL or SQL Toolbelt. You can also use the mssql plugin for the Visual Studio Code.
Finally, execute the following script to create a new database and a table for the User type.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
CREATE DATABASE Passenger USE Passenger CREATE TABLE Users ( Id uniqueidentifier primary key not null, Email nvarchar(100) not null, Password nvarchar(200) not null, Salt nvarchar(200) not null, Username nvarchar(100) not null, FullName nvarchar(100), Role nvarchar(10), CreatedAt datetime not null, UpdatedAt datetime not null ) |
Entity Framework Core
Entity Framework Core is a new version of EF ORM (Object-relational mapping) designed to provide an access to the SQL Server database. It’s one of the most popular libraries for storing and retrieving the data from the SQL Server, as well as configuring the classes and the mappings between our models and database tables. Once we install the required dependencies, we can create a new DbContext which will be responsible for handling the connection:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class PassengerContext : DbContext { private readonly SqlSettings _settings; public DbSet<User> Users { get; set; } public PassengerContext(DbContextOptions<PassengerContext> options, SqlSettings settings) : base(options) { _settings = settings; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if(_settings.InMemory) { optionsBuilder.UseInMemoryDatabase(); return; } optionsBuilder.UseSqlServer(_settings.ConnectionString); } protected override void OnModelCreating(ModelBuilder modelBuilder) { var itemBuilder = modelBuilder.Entity<User>(); itemBuilder.HasKey(x => x.Id); } } |
Now, we can implement the UserRepository:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
public class UserRepository : IUserRepository, ISqlRepository { private readonly PassengerContext _context; public UserRepository(PassengerContext context) { _context = context; } public async Task<User> GetAsync(Guid id) => await _context.Users.SingleOrDefaultAsync(x => x.Id == id); public async Task<User> GetAsync(string email) => await _context.Users.SingleOrDefaultAsync(x => x.Email == email); public async Task<IEnumerable<User>> GetAllAsync() => await _context.Users.ToListAsync(); public async Task AddAsync(User user) { await _context.Users.AddAsync(user); await _context.SaveChangesAsync(); } public async Task RemoveAsync(Guid id) { var user = await GetAsync(id); _context.Users.Remove(user); await _context.SaveChangesAsync(); } public async Task UpdateAsync(User user) { _context.Users.Update(user); await _context.SaveChangesAsync(); } } |
And finally, include the required services within Startup class:
1 2 3 |
services.AddEntityFrameworkSqlServer() .AddEntityFrameworkInMemoryDatabase() .AddDbContext<PassengerContext>(); |
The proper connection string using some default credentials may look like this: Server=localhost;User Id=SA;Password=abcd1234;Database=Passenger.
Next
In the next episode, we will focus on publishing and deploy our application using tools such as Docker, Nginx and uploading it to the cloud where we will run a virtual machine containing Ubuntu Server.
Can you do an tutorial about automating publishing applications to windows server (IIS) with automated tests ? And can you recommend something like https://travis-ci.com but up to 10-20 $ a month for closed source projects ? (or even better for free )
Hey, please take a look at my previous posts. I did a tutorial about Travis CI, BitBucket Pipelines (that’s a great alternative) and others. I’m not using IIS unfortunately, but it should be pretty much the same scenario as publishing the application to the Ubuntu Servers, especially if you use Docker.
Pingback: Dew Drop - July 17, 2017 (#2521) - Morning Dew
Witaj Piotrze, czy masz w planach rozwinąć temat migracji oraz Fluent Migratora ?
Cześć, nie będę się już zgłębiał w te tematy.
A w ramach bloga masz jakiś plan rozwinąć troszkę te 2 tematy w przyszłości ?
Raczej na pewno nie, przynajmniej nie w najbliższej przyszłości. Praktycznie nie używam już baz SQL, do tych zagadnień jest masa przykładów w sieci, a poza tym i tak nie użyłbym aktualnej wersji EF Core produkcyjnie.
A jakiego obecnie użyłbyś ORM do baz SQL? Dapper, czy jeszcze coś innego?
Jest kilka ciekawych możliwości m.in. wspomniany Dapper, a pełna lista tutaj.
Why create repository? This is abstraction over abstraction. Why not use the EF in the services directly? What is the point?
Second question. This is a thing that I have seen many times. Returning the entire record (entity) from the database. Retrieving record using this repository for the User, it gets all the fields from database. What if e. eg. we want only user id and name for drop down list? We can have 20+ fields in the table, but only need two for this specific user case. So what to do? Get all of them this is a waste of resources. Moreover this is a simple SELECT * FROM … This is not how databases should be quering.
Using the repository pattern I was created specific methods for specific queries with custom DTOs, but this is a garbage in the repository. Even creating them as a extension methods. So I’m not sold for this pattern. But still looking for a hints from others that may have different different points of view.
Thanks for pointing this out, I’m aware of all of these things, but in case you have not noticed, this was a basic video about SQL Server + EF, not an in-depth tutorial lasting a few hours. Besides that topic, DbContext is a repository and UOW itself, but due to its poor design is not an interface, thus injecting a class directly into application services makes them impossible to test. I’m not a fan of EF and not a fan of using a repository with DbContext either, however, if you look at the repository like at some generic interface, you’re missing the whole point of the domain.
W jaki sposób do projektu byś zaczął implementować frontend np. Angular4 od strony architektury ? Nowy projekt typu Passager.WebSite czy w samym Api i komunikacja między 2 stronami? Mógłbyś troszkę nakierować jak by można to prawidłowo wykonać ?
Osobny projekt w osobnym repozytorium, czysty JS + wybrany framework, komunikacja przez API, które uruchamiasz lokalnie i tyle :).
Może moje pytanie śmiesznie zabrzmi ale czy na produkcji nie wzrośnie delay pomiędzy odpowiedziami API do Website ? (Wszystko by było na 1 serwerze)
Nie, tak się to po prostu robi.
Witaj Piotrze, jakie masz plany na przyszłość rozumiem że w najbliższym odcinku jak wspomniałeś docker, a co w 24 ? I potem planujesz jeszcze tworzyć jakieś kursy płatne / bezpłatne ? Masz jakieś realne plany na chwilę obecną ?
I kiedy możemy się spodziewać kolejnego odc kursu : )?
Ogólnie świetna robota z całym kursem. Planujesz również jakiś update artykułów pod .NET Core 2.0 ?
Cześć, na ostatni odcinek mam pewien pomysł ale wyjdzie w praniu czy go zrealizuję :). Natomiast nr 23 powinien być dostępny jutro.
Wydałem ostatnio jeden kurs dla Packt Publishing (po angielsku), pracuję teraz nad kolejnym, prawdopodobnie również przygotuję coś dla Udemy Polska. Natomiast co do samego YouTube to mam trochę pomysłów co dalej z kanałem ale myślę jeżeli coś ruszy to na przełomie sierpnia/września. Jak wyjdzie stabilna wersja 2.0 to pewnie się za nią wezmę.
A masz w planach poruszać w kursach jakieś bardziej złożone tematy lub bardziej się zagłębiać w pewne tematy ?
W przyszłości tak.
Ogólnie moja propozycja jest taka żebyś może uaktywnił newsletter ? Bo niby jest ale w sumie nic z niego nie przychodzi 😛 Fajnie by było dostawać informację co wrzucasz / co się dzieje w świecie / jakieś nowe info o planach / kursach
Co sądzisz ??
Jak najbardziej, mam to w planach tylko ostatnio co innego zajmuje mi czas, ale co do samego YT mam sporo pomysłów więc na pewno wszystko ruszy w niedalekiej przyszłości :).
A czy użycie using z context w repo ma sens?
Nie za bardzo, context lepiej wstrzyknąć, jak stworzysz nowy “z palca”, to nie masz nad nim kontroli + trzeba pamiętać, że wszystko to co się dzieje w bloku using należy tylko do tego contextu.