Integrating Identity Framework (Individual User Accounts)

When we select Individual User Accounts as Authentication Method while creating a new project (MVC Framework in this case) we have Identity Framework added to our solution with a basic default configuration.

Here is a list of the main components that are added:

  • AccountController: it handles the user’s registration, login and logout. It includes as well user’s validation and complementary workflows, such as the Reset Password workflow and the Forget Password workflow. Is a sample controller with the most common configuration that can be customized for our needing.
  • AccountViewModels/Account Views: view models and views for the AccountController.
  • ManageController: it handles the user management pages in our MVC Framework application. Is complementary with the AccountController. Is a sample controller with the most common configuration that can be customized for our needing.
  • ManageViewModels/Manage Views: view models and views for the ManageController.
  • IdentityModels: here we can find the Identity EF Context. It works as for a normal EF Code First application. The ApplicationUser class can be extended to add custom properties that we want to store for our users.

The IdentityConfig.cs and Startup.Auth.cs files are added as well under the App_Start folder. This files contain many classes that can be used to configure many behaviors, such as the email/SMS services to send email and SMS, the password strength requirements, the cookie authentication policy and so on.

Identity Framework uses OWIN (Open Web Interface for .Net) to decouple our application from the web server. This allow the application to work with different configurations of OS + WebServer, without being tied to Windows and IIS.


Setting the target DB for Identity Framework Data

As for any other EF Code first application we can do this by setting the connection string when we create the context:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base(@"Data Source=.\SQLEXPRESS;Initial Catalog=TestIdentityDB;Integrated Security=True", throwIfV1Schema: false)
    {
    }
 
    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

At the first attempt to access the DB this will be created (as for any normal EF Code First application). Here is its general structure:

The tables are all empty. If we try to register a new user a record will be created into the AspNetUsers table. Here is how it looks like:


Setting an action to require authentication

We can use the Authorize attribute to specify an action that requires authentication. An user that isn’t logged in will be sent to the login page if he tries to access the action.

[Authorize]
public ActionResult AuthenticatedPage()
{
    return View();
}

From the view is always possible to access the current user’s information through the User.Identity object:

@using Microsoft.AspNet.Identity
 
@{
    ViewBag.Title = "AuthenticatedPage";
}
 
<h2>AuthenticatedPage</h2>
<h3>Welcome @User.Identity.GetUserName()</h3>

Setting an action to not require authentication

The Authorize attribute can be set also at controller-level. This means that all the controller’s actions will inherit the attribute without needing a specific configuration. In this scenario where the authentication is required as default behavior we can use the AllowAnonymous attribute to specify that an action shouldn’t require authentication.

[Authorize]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
 
    public ActionResult About()
    {
        ViewBag.Message = "Your application description page.";
 
        return View();
    }
 
    public ActionResult Contact()
    {
        ViewBag.Message = "Your contact page.";
 
        return View();
    }
 
    [AllowAnonymous]
    public ActionResult AuthenticatedPage()
    {
        return View();
    }
}

Setting an action to require role-based authentication

In addition to just requiring our user to be somehow authenticated in order to access a certain action, we can also require that the user is part of some authorization group (administrators for instance). In order to do this we need, first of all, to have users associated with roles into our Identity database. This can be easily done through a custom EF Initializer that will seed our Code First database with some basic user and role:

public class IdentityInitializer : DropCreateDatabaseAlways<ApplicationDbContext>
{
    protected override void Seed(ApplicationDbContext context)
    {
        var passwordHasher = new PasswordHasher();
 
        var adminRole = new IdentityRole("Admin");
        var testRole = new IdentityRole("Test");
 
        var adminUser = new ApplicationUser
        {
            UserName = "admin@admin.com",
            Email = "admin@admin.com",
            PasswordHash = passwordHasher.HashPassword("admin"),
            SecurityStamp = Guid.NewGuid().ToString()
        };
        adminUser.Roles.Add(new IdentityUserRole
        {
            UserId = adminUser.Id,
            RoleId = adminRole.Id
        });
 
        var testUser = new ApplicationUser
        {
            UserName = "test@test.com",
            Email = "test@test.com",
            PasswordHash = passwordHasher.HashPassword("test"),
            SecurityStamp = Guid.NewGuid().ToString()
        };
        testUser.Roles.Add(new IdentityUserRole
        {
            UserId = testUser.Id,
            RoleId = testRole.Id
        });
 
        //Creates Roles
        context.Roles.Add(adminRole);
        context.Roles.Add(testRole);
 
        //Creates Users
        context.Users.Add(adminUser);
        context.Users.Add(testUser);
    }
}

Here is what the code above will insert into the database:

Now that our users are linked to roles we can specify, for instance, an action that will be accessible only for users in the “Admin” group. An user that isn’t part of that group will be sent to the login page if he tries to access the action. We can do this in a very easy way by passing some argument to the Authorize attribute.

[Authorize(Roles = "Admin")]
public ActionResult AuthenticatedPage()
{
    return View();
}

Performing a Join on EF with Linq or Lambda expressions

Linq

Here is an example on how to join two entities (wCompPlayers and wCompPlayerTeams) to search for a player given surname and team id.

public PlayerModel GetBySurnameAndTeamId(string surname, int teamId)
{
    return (
        from p in _context.wCompPlayers
        from pt in _context.wCompPlayerTeams
        where p.IdPlayer == pt.IdPlayer
            && string.Equals(p.Surname, surname) && pt.IdTeam == teamId
        select p
        ).ToList().Select(CreatePlayerModel).FirstOrDefault();
}

Notice that we use the ToList() method to force the query to be evaluated and to have a list of results. In this way all the next steps will be evaluated only using Linq, without adding complexity to the generated underlying SQL.


Lambda

Here is the same search made with a Lambda expression. Notice that in this case we are using the AsEnumerable() method as we was using the ToList() method in the previous example: all the next steps will be evaluated without adding complexity to the generated underlying SQL.

public PlayerModel GetBySurnameAndTeamId(string surname, int teamId)
{
    return
        _context.wCompPlayers.Join(_context.wCompPlayerTeams,
            p => p.IdPlayer, pt => pt.IdPlayer, (p, pt) => new { p, pt })
            .Where(m => string.Equals(m.p.Surname, surname) && m.pt.IdTeam == teamId)
            .AsEnumerable().Select(m => CreatePlayerModel(m.p)).FirstOrDefault();
}

The Join() method accepts 4 parameters:

  • The object to join
  • An expression which returns the original object’s key to use for the join
  • An expression which returns the joined object’s key to use for the join
  • An expression which returns the joined object

Entity Framework Repository Test Example

Since we are using the Entity Framework’s context object as dependency we should consider this test as an integration test (unless we want to mock EF). Here is the test code:

public class PasswordEntryRepositoryTest
{
    [TestFixture]
    public class When_Password_Entry_Repository_Is_Present
    {
        private DbContext _context;
        private DbContextTransaction _transaction;
        private IRepository<PasswordEntry, string> _passwordEntryRepository;
 
        [SetUp]
        public void SetUp()
        {
            _context = new PasswordAPIContext();
            _transaction = _context.Database.BeginTransaction();
            _passwordEntryRepository = new PasswordEntryRepository(_context);
        }
 
        [Test]
        public void It_Should_Create_A_Password_Entry()
        {
            var item = new PasswordEntry
            {
                UserId = "user",
                Salt = "salt",
                PasswordHash = "passwordHash",
                Expiration = DateTime.Now
            };
            Assert.DoesNotThrow(() => _passwordEntryRepository.AddNew(item));
        }
 
        [Test]
        public void It_Should_Read_All_The_Password_Entries()
        {
            var item = new PasswordEntry
            {
                UserId = "user",
                Salt = "salt",
                PasswordHash = "passwordHash",
                Expiration = DateTime.Now
            };
            _passwordEntryRepository.AddNew(item);
            Assert.IsTrue(_passwordEntryRepository.GetAll().Any());
        }
 
        [Test]
        public void It_Should_Read_A_Password_Entry_By_User()
        {
            var item = new PasswordEntry
            {
                UserId = "user",
                Salt = "salt",
                PasswordHash = "passwordHash",
                Expiration = DateTime.Now
            };
            _passwordEntryRepository.AddNew(item);
            var dbItem = _passwordEntryRepository.GetById("user");
            Assert.AreEqual(item.UserId, dbItem.UserId);
        }
 
        [Test]
        public void It_Should_Update_A_Password_Entry()
        {
            var item = new PasswordEntry
            {
                UserId = "user",
                Salt = "salt",
                PasswordHash = "passwordHash",
                Expiration = DateTime.Now
            };
            _passwordEntryRepository.AddNew(item);
            item.Salt = "saltUpdated";
            _passwordEntryRepository.Update(item);
            var dbItem = _passwordEntryRepository.GetById("user");
            Assert.AreEqual(item.Salt, dbItem.Salt);
        }
 
        [Test]
        public void It_Should_Delete_A_Password_Entry()
        {
            var item = new PasswordEntry
            {
                UserId = "user",
                Salt = "salt",
                PasswordHash = "passwordHash",
                Expiration = DateTime.Now
            };
            _passwordEntryRepository.AddNew(item);
            _passwordEntryRepository.Delete(item.UserId);
            var dbItem = _passwordEntryRepository.GetById("user");
            Assert.IsNull(dbItem);
        }
 
        [TearDown]
        public void TearDown()
        {
            _transaction.Rollback();
            _transaction.Dispose();
            _context.Dispose();
        }
    }
}

Entity Framework – Lazy Loading, Direct Loading, Eagerly Loading

Every time we get an entity from EF the related entities are not automatically loaded. They will be loaded at the first attempt to access, so that from user’s point of view anything changes. This mechanism is called Lazy loading. Here is a little example:

Person person;
using (var cont = new TestDBEntities())
{
    person = cont.Persons.First(p => p.IdPerson == 1);
 
    var cityName = person.City.CityName;
    var genderName = person.Gender.GenderName;
    var carDescription = person.Cars.First().CarDescription;
}

This code works with no problems. The related entities City, Gender and Cars are automatically downloaded at first access, so we can read their fields without realizing that the Lazy Loading is working behind the scenes. We can instead realize it with the following change:

Person person;
using (var cont = new TestDBEntities())
{
    person = cont.Persons.First(p => p.IdPerson == 1);
}
 
var cityName = person.City.CityName;
var genderName = person.Gender.GenderName;
var carDescription = person.Cars.First().CarDescription;

In this case we can see the Lazy Loading at works, because at the first attempt to access a related entity we’ll get an exception telling that: “The ObjectContext instance has been disposed and can no longer be used for operations that require a connection”.

What does it means? It means that when we first try to access to read a property, the Lazy Loading attempt to load the related entity from the database, failing because the EF context has been disposed. If we look at the related entities in this moment they are all = null. This is a situation that we can easily have if we work with MVC Framework, where we could have some code like this within our controller:

public ActionResult MyAction()
{
    using (var cont = new TestDBEntities())
    {
        return View(cont.Persons.First(p => p.IdPerson == 1));
    }
}

If we try to access a related entity from the Razor view related with this action we’ll get the same error. This because when the Razor view is processed the controller’s action has already returned and our EF context has already been disposed.

So how can we do if we are in this situation? There are many solution, the simplest one it to explicitly pre-load all the related entities. This mechanism is called Explicit Loading and works taking advantage on the EF cache, where all the entities loaded from previous queries are stored to be reused. EF only uses the Lazy Loading for related entities not yet in the cache. Those which are already present will be automatically assigned without needing any extra access to the DB. Here is an example:

Person person;
using (var cont = new TestDBEntities())
{
    person = cont.Persons.First(p => p.IdPerson == 1);
    cont.Cities.Where(c => c.IdCity == person.IdCity).Load();
    cont.Genders.Where(g => g.IdGender == person.IdGender).Load();
    cont.Cars.Where(c => c.IdPerson == person.IdPerson).Load();
}
 
var cityName = person.City.CityName;
var genderName = person.Gender.GenderName;
var carDescription = person.Cars.First().CarDescription;

If we try to run this example we’ll see that the City and the Gender are loaded, while the related Cars are still not present. That’s because the Explicit Loading only works with related entities on the N-side of a 1:N relationship. The Cars are on the 1-side of a 1:N relationship, so EF can’t be sure that the pre-loaded Cars in its cache are all the cars needed, so it leave the reference = null. To have the Cars loaded as well we need to change our code in this way:

Person person;
using (var cont = new TestDBEntities())
{
    person = cont.Persons.First(p => p.IdPerson == 1);
    cont.Cities.Where(c => c.IdCity == person.IdCity).Load();
    cont.Genders.Where(g => g.IdGender == person.IdGender).Load();
    cont.Entry(person).Collection(p => p.Cars).Load();
}
 
var cityName = person.City.CityName;
var genderName = person.Gender.GenderName;
var carDescription = person.Cars.First().CarDescription;

Another approach is to ask EF to directly include the related entities we are interested in while is loading our person. This mechanism is called Eagerly Loading and is probably the most clean we can use:

Person person;
using (var cont = new TestDBEntities())
{
    person = cont.Persons.Include(p => p.City)
        .Include(p => p.Gender).Include(p => p.Cars).First(p => p.IdPerson == 1);
}
 
var cityName = person.City.CityName;
var genderName = person.Gender.GenderName;
var carDescription = person.Cars.First().CarDescription;

Entity Framework Repositories (Part 2)

This example tries to achieve the same result as the previous post, but with the cooperation of many dedicated repositories (one for each entity), in order to distribute the complexity.

The Car Repository (no dependencies)

public class CarRepository : IRepository<Car, int>
{
    private readonly DbContext _context;
 
    public CarRepository(DbContext context)
    {
        _context = context;
    }
 
    public IEnumerable<Car> GetAll()
    {
        return _context.Set<Car>().ToList();
    }
 
    public Car GetById(int id)
    {
        return _context.Set<Car>().Find(id);
    }
 
    public Car AddNew(Car entity, bool saveChanges = true)
    {
        return AddUpdate(entity, saveChanges);
    }
 
    public Car Update(Car entity, bool saveChanges = true)
    {
        return AddUpdate(entity, saveChanges);
    }
 
    public void Delete(int id, bool saveChanges = true)
    {
        var car = GetById(id);
        _context.Set<Car>().Remove(car);
        if (saveChanges)
            _context.SaveChanges();
    }
 
    public void SaveChanges()
    {
        _context.SaveChanges();
    }
 
    private Car AddUpdate(Car entity, bool saveChanges)
    {
        Car car;
        if (entity.IdCar == 0)
        {
            car = _context.Set<Car>().Create();
            _context.Set<Car>().Add(car);
        }
        else
            car = GetById(entity.IdCar);
        _context.Entry(car).CurrentValues.SetValues(entity);
        if (saveChanges)
            _context.SaveChanges();
        return car;
    }
}

The Person Repository (Car as dependency)

public class PersonRepository : IRepository<Person, int>
{
    private readonly DbContext _context;
    private readonly IRepository<Car, int> _carRepository;
 
    public PersonRepository(DbContext context,
        IRepository<Car, int> carRepository)
    {
        _context = context;
        _carRepository = carRepository;
    }
 
    public IEnumerable<Person> GetAll()
    {
        return _context.Set<Person>().ToList();
    }
 
    public Person GetById(int id)
    {
        return _context.Set<Person>().Find(id);
    }
 
    public Person AddNew(Person entity, bool saveChanges = true)
    {
        return AddUpdate(entity, saveChanges);
    }
 
    public Person Update(Person entity, bool saveChanges = true)
    {
        return AddUpdate(entity, saveChanges);
    }
 
    public void Delete(int id, bool saveChanges = true)
    {
        var person = GetById(id);
 
        //Delete dependencies before deleting
        person.Cars.ToList().ForEach(car =>
            _carRepository.Delete(car.IdCar, false));
        _context.Set<Person>().Remove(person);
        if (saveChanges)
            _context.SaveChanges();
    }
 
    public void SaveChanges()
    {
        _context.SaveChanges();
    }
 
    private Person AddUpdate(Person entity, bool saveChanges)
    {
        Person person;
        if (entity.IdCity == 0)
        {
            person = _context.Set<Person>().Create();
            _context.Set<Person>().Add(person);
        }
        else
            person = GetById(entity.IdPerson);
        _context.Entry(person).CurrentValues.SetValues(entity);
 
        //Delete dependencies before updating
        person.Cars.Where(car => entity.Cars.All(entityCar =>
            entityCar.IdCar != car.IdCar)).ToList().ForEach(car =>
                _carRepository.Delete(car.IdCar, false));
 
        //Add/Update dependecies before updating
        entity.Cars.ToList().ForEach(entityCar =>
        {
            //Ensures that the FK is set
            entityCar.IdPerson = entity.IdPerson;
            if (entityCar.IdCar == 0)
                person.Cars.Add(_carRepository.AddNew(entityCar, false));
            else
                _carRepository.Update(entityCar, false);
        });
        if (saveChanges)
            _context.SaveChanges();
        return person;
    }
}

The City Repository (Person as Dependency)

public class CityRepository2 : IRepository<City, int>
{
    private readonly DbContext _context;
    private readonly IRepository<Person, int> _personRepository;
 
    public CityRepository2(DbContext context,
        IRepository<Person, int> personRepository)
    {
        _context = context;
        _personRepository = personRepository;
    }
 
    public IEnumerable<City> GetAll()
    {
        return _context.Set<City>().ToList();
    }
 
    public City GetById(int id)
    {
        return _context.Set<City>().Find(id);
    }
 
    public City AddNew(City entity, bool saveChanges = true)
    {
        return AddUpdate(entity, saveChanges);
    }
 
    public City Update(City entity, bool saveChanges = true)
    {
        return AddUpdate(entity, saveChanges);
    }
 
    public void Delete(int id, bool saveChanges = true)
    {
        var city = GetById(id);
 
        //Delete dependencies before deleting
        city.Persons.ToList().ForEach(person =>
            _personRepository.Delete(person.IdPerson, false));
        _context.Set<City>().Remove(city);
        if (saveChanges)
            _context.SaveChanges();
    }
 
    public void SaveChanges()
    {
        _context.SaveChanges();
    }
 
    private City AddUpdate(City entity, bool saveChanges)
    {
        City city;
        if (entity.IdCity == 0)
        {
            city = _context.Set<City>().Create();
            _context.Set<City>().Add(city);
        }
        else
            city = GetById(entity.IdCity);
        _context.Entry(city).CurrentValues.SetValues(entity);
 
        //Delete dependencies before updating
        city.Persons.Where(person => entity.Persons.All(entityPerson =>
            entityPerson.IdPerson != person.IdPerson)).ToList().ForEach(person =>
                _personRepository.Delete(person.IdPerson, false));
 
        //Add/Update dependecies before updating
        entity.Persons.ToList().ForEach(entityPerson =>
        {
            //Ensures that the FK is set
            entityPerson.IdCity = entity.IdCity;
            if (entityPerson.IdPerson == 0)
                city.Persons.Add(_personRepository.AddNew(entityPerson, false));
            else
                _personRepository.Update(entityPerson, false);
        });
        if (saveChanges)
            _context.SaveChanges();
        return city;
    }
}

Entity Framework Repositories (Part 1)

Is often useful to use the Repository pattern with EF. Unfortunalely EF doen’t behave as we could expect when interacting for the basic CRUD operations. For example when we delete an entity it doesn’t delete its dependencies on cascade (it try to set their FK to NULL instead, causing DB errors at save time). In addition is difficult to insert/update complex entities (for example an entire object together with its dependencies at the same time), when we don’t just load an entity, change one or two fields, and save it again, like in the 99% of the provided examples. For instance several solutions attempt to directly insert detached POCO entities, without using the Create() method. Doing in this way the insert works, but the entity will not be converted to a EF proxy object and the navigation properties will not be updated. This example tries to show a complete repository that can be easily used on real scenarios. The repository works with City entities on this data structure:

The generic Interface

public interface IRepository<T, in TK>
{
    IEnumerable<T> GetAll();
    T GetById(TK id);
    T AddNew(T entity, bool saveChanges = true);
    T Update(T entity, bool saveChanges = true);
    void Delete(TK id, bool saveChanges = true);
    void SaveChanges();
}

The Implementation

public class CityRepository : IRepository<City, int>
{
    private readonly DbContext _context;
 
    public CityRepository(DbContext context)
    {
        _context = context;
    }
 
    public IEnumerable<City> GetAll()
    {
        return _context.Set<City>().ToList();
    }
 
    public City GetById(int id)
    {
        return _context.Set<City>().Find(id);
    }
 
    public City AddNew(City entity, bool saveChanges = true)
    {
        return AddUpdate(entity, saveChanges);
    }
 
    public City Update(City entity, bool saveChanges = true)
    {
        return AddUpdate(entity, saveChanges);
    }
 
    public void Delete(int id, bool saveChanges = true)
    {
        var city = GetById(id);
 
        //Delete dependencies before deleting
        _context.Set<Car>().RemoveRange(city.Persons
            .SelectMany(person => person.Cars));
        _context.Set<Person>().RemoveRange(city.Persons);
        _context.Set<City>().Remove(city);
        if (saveChanges)
            _context.SaveChanges();
    }
 
    public void SaveChanges()
    {
        _context.SaveChanges();
    }
 
    private City AddUpdate(City entity, bool saveChanges)
    {
        City city;
        if (entity.IdCity == 0)
        {
            city = _context.Set<City>().Create();
            _context.Set<City>().Add(city);
        }
        else
            city = GetById(entity.IdCity);
        _context.Entry(city).CurrentValues.SetValues(entity);
 
        //Delete dependencies before updating
        _context.Set<Car>().RemoveRange(city.Persons
            .SelectMany(person => person.Cars)
            .Where(car => entity.Persons
                .SelectMany(entityPerson => entityPerson.Cars)
                .All(entityCar => entityCar.IdCar != car.IdCar)));
        _context.Set<Person>().RemoveRange(city.Persons
            .Where(person => entity.Persons
                .All(entityPerson =>
                    entityPerson.IdPerson != person.IdPerson)));
 
        //Add/Update dependecies before updating
        entity.Persons.ToList().ForEach(entityPerson =>
        {
            //Ensures that the FK is set
            entityPerson.IdCity = entity.IdCity;
 
            Person person;
            if (entityPerson.IdPerson == 0)
            {
                person = _context.Set<Person>().Create();
                city.Persons.Add(person);
            }
            else
                person = _context.Set<Person>().Find(entityPerson.IdPerson);
            _context.Entry(person).CurrentValues.SetValues(entityPerson);
            entityPerson.Cars.ToList().ForEach(entityCar =>
            {
                //Ensures that the FK is set
                entityCar.IdPerson = entityPerson.IdPerson;
 
                Car car;
                if (entityCar.IdCar == 0)
                {
                    car = _context.Set<Car>().Create();
                    person.Cars.Add(car);
                }
                else
                    car = _context.Set<Car>().Find(entityCar.IdCar);
                _context.Entry(car).CurrentValues.SetValues(entityCar);
            });
        });
        if (saveChanges)
            _context.SaveChanges();
        return city;
    }
}

The Test Class (NUnit)

[TestFixture]
public class When_A_City_Repository_Is_Created
{
    private DbContext _context;
    private DbContextTransaction _transaction;
    private IRepository<City, int> _repository;
 
    [SetUp]
    public void SetUp()
    {
        _context = new TestDBEntities();
        _transaction = _context.Database.BeginTransaction();
        _repository = new CityRepository(_context);
    }
 
    [Test]
    public void It_Should_Get_All_The_Cities()
    {
        var loadedCities = _repository.GetAll();
 
        Assert.IsNotNull(loadedCities);
        Assert.IsTrue(loadedCities.Any());
        Assert.IsTrue(loadedCities.SelectMany(c => c.Persons).Any());
    }
 
    [Test]
    public void It_Should_Get_A_City_By_Id()
    {
        const int id = 1;
        var loadedCity = _repository.GetById(id);
 
        Assert.IsNotNull(loadedCity);
        Assert.AreEqual(loadedCity.IdCity, id);
        Assert.IsTrue(loadedCity.Persons.Any());
    }
 
    [Test]
    public void It_Should_Add_A_New_City()
    {
        var city = new City
        {
            CityName = "TestCity",
        };
        var addedCity = _repository.AddNew(city);
 
        Assert.AreNotEqual(addedCity.IdCity, 0);
        Assert.AreEqual(addedCity.CityName, city.CityName);
    }
 
    [Test]
    public void It_Should_Add_A_New_City_With_Dependencies()
    {
        var city = new City
        {
            CityName = "TestCity",
            Persons = new List<Person>
            {
                new Person
                {
                    Name = "TestPersonName1",
                    Surname = "TestPersonSurname1",
                    IdGender = 1,
                    Cars = new List<Car>
                    {
                        new Car{ CarDescription = "Person1Car1"},
                        new Car{ CarDescription = "Person1Car2"}
                    }
                },
                new Person
                {
                    Name = "TestPersonName2",
                    Surname = "TestPersonSurname2",
                    IdGender = 2,
                    Cars = new List<Car>
                    {
                        new Car{ CarDescription = "Person2Car1"},
                        new Car{ CarDescription = "Person2Car2"}
                    }
                }
            }
        };
        var addedCity = _repository.AddNew(city);
 
        Assert.AreNotEqual(addedCity.IdCity, 0);
        Assert.AreEqual(addedCity.CityName, city.CityName);
        Assert.IsTrue(addedCity.Persons.Count() == 2);
 
        var firstPerson = addedCity.Persons.First();
        Assert.AreNotEqual(firstPerson.IdPerson, 0);
        Assert.AreEqual(firstPerson.IdCity, addedCity.IdCity);
        Assert.AreEqual(firstPerson.Name, "TestPersonName1");
        Assert.IsNotNull(firstPerson.Gender);
        Assert.IsTrue(firstPerson.Cars.Count() == 2);
 
        var firstCar = firstPerson.Cars.First();
        Assert.AreNotEqual(firstCar.IdCar, 0);
        Assert.AreEqual(firstCar.IdPerson, firstPerson.IdPerson);
        Assert.AreEqual(firstCar.CarDescription, "Person1Car1");
    }
 
    [Test]
    public void It_Should_Update_A_City()
    {
        const int id = 1;
        var city = new City
        {
            IdCity = id,
            CityName = "UpdatedCity"
        };
        var uploadedCity = _repository.Update(city);
 
        Assert.AreEqual(uploadedCity.CityName, city.CityName);
    }
 
    [Test]
    public void It_Should_Update_A_City_With_Dependencies()
    {
        const int id = 1;
        var city = new City()
        {
            IdCity = id,
            CityName = "UpdatedCity",
            Persons = new List<Person>
            {
                new Person
                {
                    IdPerson = 2,
                    Name = "UpdatedPersonName",
                    Surname = "UpdatedPersonSurname",
                    IdGender = 2,
                    Cars = new List<Car>
                    {
                        new Car
                        {
                            IdCar = 3,
                            CarDescription = "UpdatedCar"
                        },
                        new Car
                        {
                            CarDescription = "AddedCar"
                        }
                    }
                }
            }
        };
        var uploadedCity = _repository.Update(city);
 
        Assert.AreEqual(uploadedCity.CityName, city.CityName);
        Assert.IsTrue(uploadedCity.Persons.Count() == 1);
 
        var firstPerson = uploadedCity.Persons.First();
        Assert.AreEqual(firstPerson.IdPerson, 2);
        Assert.AreEqual(firstPerson.Name, "UpdatedPersonName");
        Assert.IsTrue(firstPerson.Cars.Count() == 2);
 
        var car1 = firstPerson.Cars.ElementAt(0);
        Assert.AreEqual(car1.IdCar, 3);
        Assert.AreEqual(car1.CarDescription, "UpdatedCar");
        var car2 = firstPerson.Cars.ElementAt(1);
        Assert.AreNotEqual(car2.IdCar, 0);
        Assert.AreEqual(car2.CarDescription, "AddedCar");
    }
 
    [Test]
    public void It_Should_Delete_A_City()
    {
        const int id = 1;
        _repository.Delete(id);
        var loadedCities = _repository.GetAll();
 
        Assert.IsTrue(loadedCities.All(c => c.IdCity != id));
    }
 
    [TearDown]
    public void TearDown()
    {
        _transaction.Rollback();
        _transaction.Dispose();
        _context.Dispose();
    }
}