From 653f0234ca6e3c8936f44b0286fc2e36bc41e73e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Janis=20Daniel=20Da=CC=88hne?=
 <janis.daehne2@student.uni-halle.de>
Date: Thu, 1 Aug 2019 17:14:27 +0200
Subject: [PATCH] - migration wrong fks step 1

---
 src/ClientServer/Controllers/Core/Init.cs     |  793 +-----
 src/ClientServer/Db/YapexDbContext.cs         |    2 +
 ...1144540_addFakeFksToOtherSides.Designer.cs | 2159 +++++++++++++++++
 .../20190801144540_addFakeFksToOtherSides.cs  |  111 +
 .../Migrations/YapexDbContextModelSnapshot.cs |   41 +
 .../CustomProjectTestSettings.cs              |   42 +
 .../Exercises/Solution/SolutionAssessment.cs  |    5 +
 .../Models/Exercises/Tests/TestSettings.cs    |    6 +
 .../Models/Users/GroupRolePermission.cs       |    4 +
 .../Users/Settings/CodeEditorSettings.cs      |    4 +
 .../Models/Users/SystemRolePermission.cs      |    4 +
 11 files changed, 2511 insertions(+), 660 deletions(-)
 create mode 100755 src/ClientServer/Migrations/20190801144540_addFakeFksToOtherSides.Designer.cs
 create mode 100755 src/ClientServer/Migrations/20190801144540_addFakeFksToOtherSides.cs
 create mode 100644 src/ClientServer/Models/CustomProjects/CustomProjectTestSettings.cs

diff --git a/src/ClientServer/Controllers/Core/Init.cs b/src/ClientServer/Controllers/Core/Init.cs
index a352027..3b7214a 100644
--- a/src/ClientServer/Controllers/Core/Init.cs
+++ b/src/ClientServer/Controllers/Core/Init.cs
@@ -312,666 +312,139 @@ namespace ClientServer.Controllers.Core
         }
 
 
-//        [HttpGet("migrate/markdown")]
-//        public void MigrateMarkdownFiles()
-//        {
-//            var basePath = Files.GetUploadFilePath(UploadDirType.MarkdownAssets);
-//
-//            var exDescriptions = _context.ExerciseDescriptions
-//                    .Include(p => p.Assets)
-//                    .Where(p => p.Assets.Count > 0)
-//                    .ToList()
-//                ;
-//
-//            int count = 0;
-//            foreach (var exerciseDescription in exDescriptions)
-//            {
-//                foreach (var descriptionAsset in exerciseDescription.Assets)
-//                {
-//                    //create the real file
-//
-//                    try
-//                    {
-//                        using (var transaction = _context.Database.BeginTransaction())
-//                        {
-//                            try
-//                            {
-//                                var fileRef = new FileReferenceMarkdownAsset()
-//                                {
-//                                    OriginalName = descriptionAsset.DisplayName,
-//                                    CreatedAt = (DateTime) _context.Entry(descriptionAsset)
-//                                        .Property(YapexDbContext.CreatedAt)
-//                                        .CurrentValue,
-//                                    LastUpdatedAt = (DateTime) _context.Entry(descriptionAsset)
-//                                        .Property(YapexDbContext.LastUpdatedAt).CurrentValue,
-//                                    MimeType = descriptionAsset.MimeType,
-//                                    SizeInBytes = descriptionAsset.Content.Length,
-//                                    Hash = "",
-//                                };
-//
-//                                var conn = new ExerciseDescriptionWithFileAsAssetReference()
-//                                {
-//                                    ExerciseDescription = exerciseDescription,
-//                                    FileReferenceMarkdownAsset = fileRef
-//                                };
-//
-//                                _context.ExerciseDescriptionWithFileAsAssetReferences.Add(conn);
-//                                _context.SaveChanges();
-//
-//                                if (fileRef.Id <= 0)
-//                                {
-//                                    throw new Exception("fileRef must be tracked in db context");
-//                                }
-//
-//                                try
-//                                {
-//                                    var info = new FileInfo(Path.Combine(basePath, fileRef.Id.ToString()));
-//
-//                                    if (info.Exists)
-//                                    {
-//                                        throw new Exception("file already exists");
-//                                    }
-//
-//                                    using (var stream = new FileStream(info.FullName, FileMode.Create))
-//                                    {
-//                                        stream.Write(descriptionAsset.Content, 0, descriptionAsset.Content.Length);
-//
-//                                        using (var md5 = MD5.Create())
-//                                        {
-//                                            var result = md5.ComputeHash(descriptionAsset.Content);
-//                                            fileRef.Hash = String.Join(String.Empty,
-//                                                result.Select(p => p.ToString("x2")));
-//                                        }
-//                                    }
-//                                }
-//                                catch (Exception e)
-//                                {
-//                                    Console.WriteLine(
-//                                        $"[ERROR] error creating file name: {descriptionAsset.DisplayName}");
-//                                    Console.WriteLine(e.Message);
-//                                    throw;
-//                                }
-//
-//
-//                                _context.SaveChanges();
-//                                transaction.Commit();
-//                            }
-//                            catch (Exception e)
-//                            {
-//                                transaction.Rollback();
-//                                Console.WriteLine(e);
-//                                throw;
-//                            }
-//                        }
-//
-//                        count++;
-//                    }
-//                    catch (Exception e)
-//                    {
-//                        Console.WriteLine(e);
-//                        throw;
-//                    }
-//                }
-//            }
-//
-//
-//            Response.WriteAsync("OK -" + count);
-//        }
-//
-//
-//        [HttpGet("migrate/ex/markdown")]
-//        public void MigrateMarkdownExerciseDescriptionContent()
-//        {
-//            var allDescriptions = _context.ExerciseDescriptions
-//                .Include(p => p.AssetReferences)
-//                .ThenInclude(p => p.FileReferenceMarkdownAsset)
-//                .Include(p => p.Assets)
-//                .ToList();
-//
-//
-//            int count = 0;
-//            int count2 = 0;
-//
-//            using (var transaction = _context.Database.BeginTransaction())
-//            {
-//                try
-//                {
-//                    foreach (var exerciseDescription in allDescriptions)
-//                    {
-//                        if (exerciseDescription.Content.Contains(Constants.MarkdownAssetFileUrlPrefix))
-//                        {
-//
-//                            foreach (var asset in exerciseDescription.Assets)
-//                            {
-//                                //find asset ref
-//
-//                                var assetRef = exerciseDescription.AssetReferences.FirstOrDefault(p =>
-//                                    p.FileReferenceMarkdownAsset.OriginalName == asset.DisplayName &&
-//                                    p.FileReferenceMarkdownAsset.SizeInBytes == asset.Content.Length);
-//
-//                                if (assetRef == null)
-//                                {
-//                                    throw new Exception($"could not find asset ref for asset id {asset.Id} for ex desc {exerciseDescription.Id}");
-//                                }
-//
-//                                exerciseDescription.Content = exerciseDescription.Content.Replace(asset.AssetUrl,
-//                                    Constants.MarkdownAssetFileUrlPrefix + assetRef.FileReferenceMarkdownAssetId);
-//                                count2++;
-//                            }
-//                    
-//                            count++;
-//
-//                        }
-//                    }
-//
-//                    _context.SaveChanges();
-//                    transaction.Commit();
-//                }
-//                catch (Exception e)
-//                {
-//                    transaction.Rollback();
-//                    Console.WriteLine(e);
-//                    throw;
-//                }
-//            }
-//            
-//            
-//            Response.WriteAsync($"OK - {count} - ${count2}");
-//        }
-//
-//
-//        [HttpGet("migrate/tests")]
-//        public void MigrateTestFiles()
-//        {
-//            var basePath = Files.GetUploadFilePath(UploadDirType.TestAssets);
-//
-//            var testsWithAssets = _context.Tests
-//                    .Include(p => p.TestAssets)
-//                    .Where(p => p.TestAssets.Count > 0)
-//                    .ToList()
-//                ;
-//
-//            int count = 0;
-//            foreach (var testWithAsset in testsWithAssets)
-//            {
-//                foreach (var testAsset in testWithAsset.TestAssets)
-//                {
-//                    //create the real file
-//
-//                    try
-//                    {
-//                        using (var transaction = _context.Database.BeginTransaction())
-//                        {
-//                            try
-//                            {
-//                                var fileRef = new FileReferenceTestAsset()
-//                                {
-//                                    OriginalName = testAsset.DisplayName,
-//                                    CreatedAt = (DateTime) _context.Entry(testAsset)
-//                                        .Property(YapexDbContext.CreatedAt)
-//                                        .CurrentValue,
-//                                    LastUpdatedAt = (DateTime) _context.Entry(testAsset)
-//                                        .Property(YapexDbContext.LastUpdatedAt).CurrentValue,
-//                                    MimeType = testAsset.MimeType,
-//                                    SizeInBytes = testAsset.Content.Length,
-//                                    Hash = "",
-//                                };
-//
-//                                var conn = new TestWithFileAsAssetReference()
-//                                {
-//                                    Test = testWithAsset,
-//                                    FileReferenceTestAsset = fileRef
-//                                };
-//
-//                                _context.TestWithFileAsAssetReferences.Add(conn);
-//                                _context.SaveChanges();
-//
-//                                if (fileRef.Id <= 0)
-//                                {
-//                                    throw new Exception("fileRef must be tracked in db context");
-//                                }
-//
-//                                try
-//                                {
-//                                    var info = new FileInfo(Path.Combine(basePath, fileRef.Id.ToString()));
-//
-//                                    if (info.Exists)
-//                                    {
-//                                        throw new Exception($"file already exists: {info.FullName}");
-//                                    }
-//
-//                                    using (var stream = new FileStream(info.FullName, FileMode.Create))
-//                                    {
-//                                        stream.Write(testAsset.Content, 0, testAsset.Content.Length);
-//
-//                                        using (var md5 = MD5.Create())
-//                                        {
-//                                            var result = md5.ComputeHash(testAsset.Content);
-//                                            fileRef.Hash = String.Join(String.Empty,
-//                                                result.Select(p => p.ToString("x2")));
-//                                        }
-//                                    }
-//                                }
-//                                catch (Exception e)
-//                                {
-//                                    Console.WriteLine(
-//                                        $"[ERROR] error creating file name: {testAsset.DisplayName}");
-//                                    Console.WriteLine(e.Message);
-//                                    throw;
-//                                }
-//
-//
-//                                _context.SaveChanges();
-//                                transaction.Commit();
-//                            }
-//                            catch (Exception e)
-//                            {
-//                                transaction.Rollback();
-//                                Console.WriteLine(e);
-//                                throw;
-//                            }
-//                        }
-//
-//                        count++;
-//                    }
-//                    catch (Exception e)
-//                    {
-//                        Console.WriteLine(e);
-//                        throw;
-//                    }
-//                }
-//            }
-//
-//
-//            Response.WriteAsync("OK -" + count);
-//        }
-//
-//
-//        [HttpGet("migrate/custom/tests")]
-//        public void MigrateCustomTestAssets()
-//        {
-//            var basePath = Files.GetUploadFilePath(UploadDirType.UserAssets);
-//
-//            var testsWithAssets = _context.CustomTest
-//                    .Include(p => p.TestAssets)
-//                    .Where(p => p.TestAssets.Count > 0)
-//                    .ToList()
-//                ;
-//
-//            int count = 0;
-//
-//            foreach (var customTest in testsWithAssets)
-//            {
-//                foreach (var customTestAsset in customTest.TestAssets)
-//                {
-//                    //create the real file
-//
-//                    try
-//                    {
-//                        using (var transaction = _context.Database.BeginTransaction())
-//                        {
-//                            try
-//                            {
-//                                var fileRef = new FileReferenceUserFileAsset()
-//                                {
-//                                    OriginalName = customTestAsset.DisplayName,
-//                                    CreatedAt = (DateTime) _context.Entry(customTestAsset)
-//                                        .Property(YapexDbContext.CreatedAt)
-//                                        .CurrentValue,
-//                                    LastUpdatedAt = (DateTime) _context.Entry(customTestAsset)
-//                                        .Property(YapexDbContext.LastUpdatedAt).CurrentValue,
-//                                    MimeType = customTestAsset.MimeType,
-//                                    SizeInBytes = customTestAsset.Content.Length,
-//                                    Hash = "",
-//                                };
-//
-//                                var conn = new CustomTestWithFileAsAssetReference()
-//                                {
-//                                    CustomTest = customTest,
-//                                    FileReferenceUserFileAsset = fileRef
-//                                };
-//
-//                                _context.CustomTestWithFileAsAssetReferences.Add(conn);
-//                                _context.SaveChanges();
-//
-//                                if (fileRef.Id <= 0)
-//                                {
-//                                    throw new Exception("fileRef must be tracked in db context");
-//                                }
-//
-//                                try
-//                                {
-//                                    var info = new FileInfo(Path.Combine(basePath, fileRef.Id.ToString()));
-//
-//                                    if (info.Exists)
-//                                    {
-//                                        throw new Exception($"file already exists: {info.FullName}");
-//                                    }
-//
-//                                    using (var stream = new FileStream(info.FullName, FileMode.Create))
-//                                    {
-//                                        stream.Write(customTestAsset.Content, 0, customTestAsset.Content.Length);
-//
-//                                        using (var md5 = MD5.Create())
-//                                        {
-//                                            var result = md5.ComputeHash(customTestAsset.Content);
-//                                            fileRef.Hash = String.Join(String.Empty,
-//                                                result.Select(p => p.ToString("x2")));
-//                                        }
-//                                    }
-//                                }
-//                                catch (Exception e)
-//                                {
-//                                    Console.WriteLine(
-//                                        $"[ERROR] error creating file name: {customTestAsset.DisplayName}");
-//                                    Console.WriteLine(e.Message);
-//                                    throw;
-//                                }
-//
-//
-//                                _context.SaveChanges();
-//                                transaction.Commit();
-//                            }
-//                            catch (Exception e)
-//                            {
-//                                transaction.Rollback();
-//                                Console.WriteLine(e);
-//                                throw;
-//                            }
-//                        }
-//
-//                        count++;
-//                    }
-//                    catch (Exception e)
-//                    {
-//                        Console.WriteLine(e);
-//                        throw;
-//                    }
-//                }
-//                
-//            }
-//            
-//            Response.WriteAsync("OK -" + count);
-//            
-//        }
-//        
-//        
-//        [HttpGet("migrate/custom/project/description")]
-//        public void MigrateCustomProjectDescriptionAssets()
-//        {
-//            var basePath = Files.GetUploadFilePath(UploadDirType.UserAssets);
-//
-//            var customProjectDescriptions = _context.CustomProjectDescriptions
-//                    .Include(p => p.Assets)
-//                    .Where(p => p.Assets.Count > 0)
-//                    .ToList()
-//                ;
-//
-//            int count = 0;
-//
-//            foreach (var customProjectDescription in customProjectDescriptions)
-//            {
-//                foreach (var customAsset in customProjectDescription.Assets)
-//                {
-//                    //create the real file
-//
-//                    try
-//                    {
-//                        using (var transaction = _context.Database.BeginTransaction())
-//                        {
-//                            try
-//                            {
-//                                var fileRef = new FileReferenceUserFileAsset()
-//                                {
-//                                    OriginalName = customAsset.DisplayName,
-//                                    CreatedAt = (DateTime) _context.Entry(customAsset)
-//                                        .Property(YapexDbContext.CreatedAt)
-//                                        .CurrentValue,
-//                                    LastUpdatedAt = (DateTime) _context.Entry(customAsset)
-//                                        .Property(YapexDbContext.LastUpdatedAt).CurrentValue,
-//                                    MimeType = customAsset.MimeType,
-//                                    SizeInBytes = customAsset.Content.Length,
-//                                    Hash = "",
-//                                };
-//
-//                                var conn = new CustomProjectDescriptionWithFileAsAssetReference()
-//                                {
-//                                    CustomProjectDescription = customProjectDescription,
-//                                    FileReferenceUserFileAsset = fileRef
-//                                };
-//
-//                                _context.CustomProjectDescriptionWithFileAsAssetReferences.Add(conn);
-//                                _context.SaveChanges();
-//
-//                                if (fileRef.Id <= 0)
-//                                {
-//                                    throw new Exception("fileRef must be tracked in db context");
-//                                }
-//
-//                                try
-//                                {
-//                                    var info = new FileInfo(Path.Combine(basePath, fileRef.Id.ToString()));
-//
-//                                    if (info.Exists)
-//                                    {
-//                                        throw new Exception($"file already exists: {info.FullName}");
-//                                    }
-//
-//                                    using (var stream = new FileStream(info.FullName, FileMode.Create))
-//                                    {
-//                                        stream.Write(customAsset.Content, 0, customAsset.Content.Length);
-//
-//                                        using (var md5 = MD5.Create())
-//                                        {
-//                                            var result = md5.ComputeHash(customAsset.Content);
-//                                            fileRef.Hash = String.Join(String.Empty,
-//                                                result.Select(p => p.ToString("x2")));
-//                                        }
-//                                    }
-//                                }
-//                                catch (Exception e)
-//                                {
-//                                    Console.WriteLine(
-//                                        $"[ERROR] error creating file name: {customAsset.DisplayName}");
-//                                    Console.WriteLine(e.Message);
-//                                    throw;
-//                                }
-//
-//
-//                                _context.SaveChanges();
-//                                transaction.Commit();
-//                            }
-//                            catch (Exception e)
-//                            {
-//                                transaction.Rollback();
-//                                Console.WriteLine(e);
-//                                throw;
-//                            }
-//                        }
-//
-//                        count++;
-//                    }
-//                    catch (Exception e)
-//                    {
-//                        Console.WriteLine(e);
-//                        throw;
-//                    }
-//                }
-//                
-//            }
-//            
-//            Response.WriteAsync("OK -" + count);
-//            
-//        }
-//        
-//        [HttpGet("migrate/custom/project/markdown")]
-//        public void MigrateMarkdownCustomProjectDescriptionContent()
-//        {
-//            
-//            var allDescriptions = _context.CustomProjectDescriptions
-//                .Include(p => p.AssetReferences)
-//                .ThenInclude(p => p.FileReferenceUserFileAsset)
-//                .Include(p => p.Assets)
-//                .ToList();
-//
-//
-//            int count = 0;
-//            int count2 = 0;
-//
-//            using (var transaction = _context.Database.BeginTransaction())
-//            {
-//                try
-//                {
-//                    foreach (var customProjectDescription in allDescriptions)
-//                    {
-//                        if (customProjectDescription.Content.Contains(Constants.MarkdownAssetFileUrlPrefix))
-//                        {
-//
-//                            foreach (var asset in customProjectDescription.Assets)
-//                            {
-//                                //find asset ref
-//
-//                                var assetRef = customProjectDescription.AssetReferences.FirstOrDefault(p =>
-//                                    p.FileReferenceUserFileAsset.OriginalName == asset.DisplayName &&
-//                                    p.FileReferenceUserFileAsset.SizeInBytes == asset.Content.Length);
-//
-//                                if (assetRef == null)
-//                                {
-//                                    throw new Exception($"could not find asset ref for asset id {asset.Id} for ex desc {customProjectDescription.Id}");
-//                                }
-//
-//                                customProjectDescription.Content = customProjectDescription.Content.Replace(asset.AssetUrl,
-//                                    Constants.MarkdownAssetFileUrlPrefix + assetRef.FileReferenceUserFileAssetId);
-//                                count2++;
-//                            }
-//                    
-//                            count++;
-//
-//                        }
-//                    }
-//
-//                    _context.SaveChanges();
-//                    transaction.Commit();
-//                }
-//                catch (Exception e)
-//                {
-//                    transaction.Rollback();
-//                    Console.WriteLine(e);
-//                    throw;
-//                }
-//            }
-//            
-//            
-//            Response.WriteAsync($"OK - {count} - ${count2}");
-//        }
-//        
-//        [HttpGet("migrate/custom/project/tests")]
-//        public void MigrateCustomProjectTestAssets()
-//        {
-//            var basePath = Files.GetUploadFilePath(UploadDirType.UserAssets);
-//
-//            var testsWithAssets = _context.CustomProjectTests
-//                    .Include(p => p.TestAssets)
-//                    .Where(p => p.TestAssets.Count > 0)
-//                    .ToList()
-//                ;
-//
-//            int count = 0;
-//
-//            foreach (var customProjectTest in testsWithAssets)
-//            {
-//                foreach (var customProjectTestAsset in customProjectTest.TestAssets)
-//                {
-//                    //create the real file
-//
-//                    try
-//                    {
-//                        using (var transaction = _context.Database.BeginTransaction())
-//                        {
-//                            try
-//                            {
-//                                var fileRef = new FileReferenceUserFileAsset()
-//                                {
-//                                    OriginalName = customProjectTestAsset.DisplayName,
-//                                    CreatedAt = (DateTime) _context.Entry(customProjectTestAsset)
-//                                        .Property(YapexDbContext.CreatedAt)
-//                                        .CurrentValue,
-//                                    LastUpdatedAt = (DateTime) _context.Entry(customProjectTestAsset)
-//                                        .Property(YapexDbContext.LastUpdatedAt).CurrentValue,
-//                                    MimeType = customProjectTestAsset.MimeType,
-//                                    SizeInBytes = customProjectTestAsset.Content.Length,
-//                                    Hash = "",
-//                                };
-//
-//                                var conn = new CustomProjectTestWithFileAsAssetReference()
-//                                {
-//                                    CustomProjectTest = customProjectTest,
-//                                    FileReferenceUserFileAsset = fileRef
-//                                };
-//
-//                                _context.CustomProjectTestWithFileAsAssetReferences.Add(conn);
-//                                _context.SaveChanges();
-//
-//                                if (fileRef.Id <= 0)
-//                                {
-//                                    throw new Exception("fileRef must be tracked in db context");
-//                                }
-//
-//                                try
-//                                {
-//                                    var info = new FileInfo(Path.Combine(basePath, fileRef.Id.ToString()));
-//
-//                                    if (info.Exists)
-//                                    {
-//                                        throw new Exception($"file already exists: {info.FullName}");
-//                                    }
-//
-//                                    using (var stream = new FileStream(info.FullName, FileMode.Create))
-//                                    {
-//                                        stream.Write(customProjectTestAsset.Content, 0, customProjectTestAsset.Content.Length);
-//
-//                                        using (var md5 = MD5.Create())
-//                                        {
-//                                            var result = md5.ComputeHash(customProjectTestAsset.Content);
-//                                            fileRef.Hash = String.Join(String.Empty,
-//                                                result.Select(p => p.ToString("x2")));
-//                                        }
-//                                    }
-//                                }
-//                                catch (Exception e)
-//                                {
-//                                    Console.WriteLine(
-//                                        $"[ERROR] error creating file name: {customProjectTestAsset.DisplayName}");
-//                                    Console.WriteLine(e.Message);
-//                                    throw;
-//                                }
-//
-//
-//                                _context.SaveChanges();
-//                                transaction.Commit();
-//                            }
-//                            catch (Exception e)
-//                            {
-//                                transaction.Rollback();
-//                                Console.WriteLine(e);
-//                                throw;
-//                            }
-//                        }
-//
-//                        count++;
-//                    }
-//                    catch (Exception e)
-//                    {
-//                        Console.WriteLine(e);
-//                        throw;
-//                    }
-//                }
-//                
-//            }
-//            
-//            Response.WriteAsync("OK -" + count);
-//            
-//        }
+        [HttpGet("migrate/addfks")]
+        public void MigrateMarkdownFiles()
+        {
+            var systemRoles = _context.SystemRoles
+                .Include(p => p.SystemRolePermission)
+                .ToList();
+
+            foreach (var systemRole in systemRoles)
+            {
+                systemRole.SystemRolePermission.SystemRoleId = systemRole.Id;
+            }
+
+
+            var groupRoles = _context.GroupRoles
+                    .Include(p => p.GroupRolePermission)
+                    .ToList()
+                ;
+
+            foreach (var groupRole in groupRoles)
+            {
+                groupRole.GroupRolePermission.GroupRoleId = groupRole.Id;
+            }
+
+
+            var userSettings = _context.UserSettingses
+                .Include(p => p.CodeEditorSetting)
+                .ToList();
+
+            foreach (var userSetting in userSettings)
+            {
+                userSetting.CodeEditorSetting.UserSettingId = userSetting.Id;
+            }
+
+
+            var solutions = _context.Solutions
+                .Include(p => p.Assessment)
+                .ToList();
+
+            solutions = solutions.Where(p => p.Assessment != null).ToList();
+
+            foreach (var solution in solutions)
+            {
+                solution.Assessment.PLangId = solution.PLangId;
+                solution.Assessment.UserId = solution.UserId;
+                solution.Assessment.ExerciseReleaseId = solution.ExerciseReleaseId;
+            }
+
+
+            var allTestSettings = _context.TestCaseSettingses.ToList();
+
+
+            
+            var allValidTestSettingsIds = new List<int>();
+            
+            var exTests = _context.Tests
+                    .Include(p => p.TestSettings)
+                    .ToList()
+                ;
+
+            foreach (var exTest in exTests)
+            {
+                exTest.TestSettings.TestId = exTest.Id;
+                allValidTestSettingsIds.Add(exTest.TestSettings.Id);
+            }
+
+            //we need to delete the old test settings... BUT it has on delete cascade
+            //so first migrate then drop the constraint and then remove the old test settings...
+            var customProjectTests = _context.CustomProjectTests
+                .Include(p => p.TestSettings)
+                .ToList();
+
+
+            foreach (var customProjectTest in customProjectTests)
+            {
+                var customProjectTestSettings = new CustomProjectTestSettings()
+                {
+                    Id = customProjectTest.TestSettings.Id,
+                    CompileTimeoutInMs = customProjectTest.TestSettings.CompileTimeoutInMs,
+                    CompilerOptions = customProjectTest.TestSettings.CompilerOptions,
+                    TimeoutInMs = customProjectTest.TestSettings.TimeoutInMs,
+                    MemoryLimitInKb = customProjectTest.TestSettings.MemoryLimitInKb,
+                    MaxDiskSpaceInKb = customProjectTest.TestSettings.MaxDiskSpaceInKb,
+                    CustomProjectTestId = customProjectTest.Id
+                };
+
+                _context.CustomProjectTestSettings.Add(customProjectTestSettings);
+                allValidTestSettingsIds.Add(customProjectTest.TestSettings.Id);
+            }
+
+
+            var count1 = exTests.Count + customProjectTests.Count;
+            var removedCount = 0;
+            
+            
+            //because we have the delete cascade on the wrong side... we never delete test settings...
+            foreach (var allTestSetting in allTestSettings)
+            {
+
+                if (allValidTestSettingsIds.Contains(allTestSetting.Id))
+                {
+                    //valid
+                }
+                else
+                {
+                    _context.TestCaseSettingses.Remove(allTestSetting);
+                    removedCount++;
+                }
+            }
+
+            var newCount2 = allTestSettings.Count - removedCount;
+            if (newCount2 != count1)
+            {
+                Response.WriteAsync("wrong");
+                return;
+            }
+
+            int rows;
+            try
+            {
+                rows = _context.SaveChanges();
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(e);
+                throw;
+            }
+
+
+            Response.WriteAsync("OK -" + rows);
+        }
+        
+        //remove test case settings fk on delete cascade... because when we add the new CustomProjectTestSettings we want to delete the old 
         
+       
     }
 }
diff --git a/src/ClientServer/Db/YapexDbContext.cs b/src/ClientServer/Db/YapexDbContext.cs
index 01889b4..88862aa 100644
--- a/src/ClientServer/Db/YapexDbContext.cs
+++ b/src/ClientServer/Db/YapexDbContext.cs
@@ -69,6 +69,7 @@ namespace ClientServer.Db
         public DbSet<CustomProjectSolution> CustomProjectSolutions { get; set; }
         public DbSet<CustomProjectSolutionFile> CustomProjectSolutionFiles { get; set; }
         public DbSet<CustomProjectTest> CustomProjectTests { get; set; }
+        public DbSet<CustomProjectTestSettings> CustomProjectTestSettings { get; set; }
         public DbSet<CustomProjectTestWithSolutionAsTestResult> CustomProjectTestWithSolutionAsTestResults { get; set; }
         public DbSet<CustomProjectTestAsset> CustomProjectTestAssets { get; set; }
         
@@ -155,6 +156,7 @@ namespace ClientServer.Db
             typeof(CustomProjectSolution),
             typeof(CustomProjectSolutionFile),
             typeof(CustomProjectTest),
+            typeof(CustomProjectTestSettings),
             typeof(CustomProjectTestWithSolutionAsTestResult),
             typeof(CustomProjectTestAsset),
             
diff --git a/src/ClientServer/Migrations/20190801144540_addFakeFksToOtherSides.Designer.cs b/src/ClientServer/Migrations/20190801144540_addFakeFksToOtherSides.Designer.cs
new file mode 100755
index 0000000..a3cd140
--- /dev/null
+++ b/src/ClientServer/Migrations/20190801144540_addFakeFksToOtherSides.Designer.cs
@@ -0,0 +1,2159 @@
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using ClientServer.Db;
+using ClientServer.Models.Exercises.Release;
+
+namespace ClientServer.Migrations
+{
+    [DbContext(typeof(YapexDbContext))]
+    [Migration("20190801144540_addFakeFksToOtherSides")]
+    partial class addFakeFksToOtherSides
+    {
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+            modelBuilder
+                .HasAnnotation("ProductVersion", "1.0.3");
+
+            modelBuilder.Entity("ClientServer.Models.AwaitDummy", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.HasKey("Id");
+
+                    b.ToTable("AwaitDummies");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProject", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(2000);
+
+                    b.Property<int>("LastEditorPLangId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("UserId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("CustomProjects");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectDescription", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(50000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("CustomProjectId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CustomProjectId")
+                        .IsUnique();
+
+                    b.ToTable("CustomProjectDescriptions");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectDescriptionWithFileAsAssetReference", b =>
+                {
+                    b.Property<int>("CustomProjectDescriptionId");
+
+                    b.Property<int>("FileReferenceUserFileAssetId");
+
+                    b.HasKey("CustomProjectDescriptionId", "FileReferenceUserFileAssetId");
+
+                    b.HasIndex("CustomProjectDescriptionId");
+
+                    b.HasIndex("FileReferenceUserFileAssetId");
+
+                    b.ToTable("CustomProjectDescriptionWithFileAsAssetReferences");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectSolution", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("CustomProjectId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int?>("MainFileId");
+
+                    b.Property<int>("PLangId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CustomProjectId");
+
+                    b.HasIndex("MainFileId")
+                        .IsUnique();
+
+                    b.HasIndex("PLangId");
+
+                    b.ToTable("CustomProjectSolutions");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectSolutionFile", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(70000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int?>("CustomProjectSolutionId")
+                        .IsRequired();
+
+                    b.Property<int>("DisplayIndex");
+
+                    b.Property<string>("FileNameWithExtension")
+                        .HasMaxLength(2000);
+
+                    b.Property<bool>("IsDisplayed");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CustomProjectSolutionId");
+
+                    b.ToTable("CustomProjectSolutionFiles");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTest", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(80000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("CustomProjectId");
+
+                    b.Property<int>("DisplayIndex");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("TestSettingsId");
+
+                    b.Property<int>("TestTypeId");
+
+                    b.Property<int>("Weight");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CustomProjectId");
+
+                    b.HasIndex("TestSettingsId")
+                        .IsUnique();
+
+                    b.HasIndex("TestTypeId");
+
+                    b.ToTable("CustomProjectTests");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTestAsset", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<byte[]>("Content");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("Hash")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<string>("MimeType")
+                        .HasMaxLength(2000);
+
+                    b.HasKey("Id");
+
+                    b.ToTable("CustomProjectTestAssets");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTestSettings", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("CompileTimeoutInMs");
+
+                    b.Property<string>("CompilerOptions")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("CustomProjectTestId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("MaxDiskSpaceInKb");
+
+                    b.Property<int>("MemoryLimitInKb");
+
+                    b.Property<int>("TimeoutInMs");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("CustomProjectTestSettings");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTestWithFileAsAssetReference", b =>
+                {
+                    b.Property<int>("CustomProjectTestId");
+
+                    b.Property<int>("FileReferenceUserFileAssetId");
+
+                    b.HasKey("CustomProjectTestId", "FileReferenceUserFileAssetId");
+
+                    b.HasIndex("CustomProjectTestId");
+
+                    b.HasIndex("FileReferenceUserFileAssetId");
+
+                    b.ToTable("CustomProjectTestWithFileAsAssetReferences");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTestWithSolutionAsTestResult", b =>
+                {
+                    b.Property<int>("CustomProjectSolutionId");
+
+                    b.Property<int>("CustomProjectTestId");
+
+                    b.Property<bool>("CharacterLimitExceeded");
+
+                    b.Property<int?>("CharacterLimitUsed");
+
+                    b.Property<int?>("CompileTimeoutInMsUsed");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<bool?>("HasCompiled");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<bool?>("Passed");
+
+                    b.Property<int?>("ProgramExitCode");
+
+                    b.Property<string>("Protocol")
+                        .HasMaxLength(160100);
+
+                    b.Property<string>("RunnerVersion")
+                        .HasMaxLength(2000);
+
+                    b.Property<int?>("TestResultCode");
+
+                    b.Property<string>("TestServerVersion")
+                        .HasMaxLength(2000);
+
+                    b.Property<int?>("TimeForCompiling");
+
+                    b.Property<int?>("TimeForUserProgram");
+
+                    b.Property<int?>("TimeoutInMsUsed");
+
+                    b.HasKey("CustomProjectSolutionId", "CustomProjectTestId");
+
+                    b.HasIndex("CustomProjectSolutionId");
+
+                    b.HasIndex("CustomProjectTestId");
+
+                    b.ToTable("CustomProjectTestWithSolutionAsTestResults");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.AfterSolutions.AfterSolution", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int?>("MainFileId");
+
+                    b.Property<int>("SolutionExerciseReleaseId");
+
+                    b.Property<int>("SolutionPLangId");
+
+                    b.Property<int>("SolutionUserId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("MainFileId")
+                        .IsUnique();
+
+                    b.HasIndex("SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId")
+                        .IsUnique();
+
+                    b.ToTable("AfterSolutions");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.AfterSolutions.AfterSolutionFile", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("AfterSolutionId");
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(70000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("DisplayIndex");
+
+                    b.Property<string>("FileNameWithExtension")
+                        .HasMaxLength(2000);
+
+                    b.Property<bool>("IsDisplayed");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int?>("TemplateFileId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("AfterSolutionId");
+
+                    b.HasIndex("TemplateFileId");
+
+                    b.ToTable("AfterSolutionFiles");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.AfterSolutions.CustomTestWithAfterSolutionAsTestResult", b =>
+                {
+                    b.Property<int>("CustomTestId");
+
+                    b.Property<int>("AfterSolutionId");
+
+                    b.Property<bool>("CharacterLimitExceeded");
+
+                    b.Property<int?>("CharacterLimitUsed");
+
+                    b.Property<int?>("CompileTimeoutInMsUsed");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<bool?>("HasCompiled");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<bool?>("Passed");
+
+                    b.Property<int?>("ProgramExitCode");
+
+                    b.Property<string>("Protocol")
+                        .HasMaxLength(160100);
+
+                    b.Property<string>("RunnerVersion")
+                        .HasMaxLength(2000);
+
+                    b.Property<int?>("TestResultCode");
+
+                    b.Property<string>("TestServerVersion")
+                        .HasMaxLength(2000);
+
+                    b.Property<int?>("TimeForCompiling");
+
+                    b.Property<int?>("TimeForUserProgram");
+
+                    b.Property<int?>("TimeoutInMsUsed");
+
+                    b.HasKey("CustomTestId", "AfterSolutionId");
+
+                    b.HasIndex("AfterSolutionId");
+
+                    b.HasIndex("CustomTestId");
+
+                    b.ToTable("CustomTestWithAfterSolutionAsTestResults");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.AfterSolutions.TestWithAfterSolutionAsTestResult", b =>
+                {
+                    b.Property<int>("TestId");
+
+                    b.Property<int>("AfterSolutionId");
+
+                    b.Property<bool>("CharacterLimitExceeded");
+
+                    b.Property<int?>("CharacterLimitUsed");
+
+                    b.Property<int?>("CompileTimeoutInMsUsed");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<bool?>("HasCompiled");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<bool?>("Passed");
+
+                    b.Property<int?>("ProgramExitCode");
+
+                    b.Property<string>("Protocol")
+                        .HasMaxLength(160100);
+
+                    b.Property<string>("RunnerVersion")
+                        .HasMaxLength(2000);
+
+                    b.Property<int?>("TestResultCode");
+
+                    b.Property<string>("TestServerVersion")
+                        .HasMaxLength(2000);
+
+                    b.Property<int?>("TimeForCompiling");
+
+                    b.Property<int?>("TimeForUserProgram");
+
+                    b.Property<int?>("TimeoutInMsUsed");
+
+                    b.HasKey("TestId", "AfterSolutionId");
+
+                    b.HasIndex("AfterSolutionId");
+
+                    b.HasIndex("TestId");
+
+                    b.ToTable("TestWithAfterSolutionAsTestResults");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.CodeTemplate", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("ExerciseId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int?>("MainFileId");
+
+                    b.Property<int>("PLangId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ExerciseId");
+
+                    b.HasIndex("MainFileId")
+                        .IsUnique();
+
+                    b.HasIndex("PLangId");
+
+                    b.ToTable("Templates");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.CustomTestWithFileAsAssetReference", b =>
+                {
+                    b.Property<int>("CustomTestId");
+
+                    b.Property<int>("FileReferenceUserFileAssetId");
+
+                    b.HasKey("CustomTestId", "FileReferenceUserFileAssetId");
+
+                    b.HasIndex("CustomTestId");
+
+                    b.HasIndex("FileReferenceUserFileAssetId");
+
+                    b.ToTable("CustomTestWithFileAsAssetReferences");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Exercise", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<bool>("CanUserCreateCustomTests");
+
+                    b.Property<bool>("CanUserCreateFiles");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(2000);
+
+                    b.Property<bool>("IsOnlyVisibleToOwner");
+
+                    b.Property<bool>("IsPermanentlyLocked");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<string>("Note")
+                        .HasMaxLength(10000);
+
+                    b.Property<string>("ShortDescription")
+                        .HasMaxLength(2000);
+
+                    b.Property<int>("UserGroupId");
+
+                    b.Property<int?>("UserId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("UserGroupId");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("Exercises");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.ExerciseDescription", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(50000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("ExerciseId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ExerciseId")
+                        .IsUnique();
+
+                    b.ToTable("ExerciseDescriptions");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.ExerciseDescriptionWithFileAsAssetReference", b =>
+                {
+                    b.Property<int>("ExerciseDescriptionId");
+
+                    b.Property<int>("FileReferenceMarkdownAssetId");
+
+                    b.HasKey("ExerciseDescriptionId", "FileReferenceMarkdownAssetId");
+
+                    b.HasIndex("ExerciseDescriptionId");
+
+                    b.HasIndex("FileReferenceMarkdownAssetId");
+
+                    b.ToTable("ExerciseDescriptionWithFileAsAssetReferences");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.MetaData", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("ExerciseId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ExerciseId")
+                        .IsUnique();
+
+                    b.ToTable("MetaDatas");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Release.ExerciseRelease", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime?>("AutomaticEndAt");
+
+                    b.Property<DateTime?>("AutomaticStartAt");
+
+                    b.Property<int>("AvailableWorkingTimeInMinutes");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("ExerciseId");
+
+                    b.Property<string>("GeneratedCode")
+                        .IsRequired()
+                        .HasMaxLength(2000);
+
+                    b.Property<bool>("HadAutomaticAssessmentErrors");
+
+                    b.Property<bool>("HasAutomaticAssessmentFinished");
+
+                    b.Property<bool>("HasAutomaticAssessmentStarted");
+
+                    b.Property<bool>("HasLimitedWorkingTime");
+
+                    b.Property<bool>("HideExerciseLeaveActions");
+
+                    b.Property<bool>("HideInOverviews");
+
+                    b.Property<bool>("HidePrintOptions");
+
+                    b.Property<bool>("HideSiteHeaderBar");
+
+                    b.Property<bool>("IsReleased");
+
+                    b.Property<bool>("IsVisibleToAllAfterRelease");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int?>("MaxManualPoint");
+
+                    b.Property<string>("Note")
+                        .HasMaxLength(10000);
+
+                    b.Property<int>("PLangId");
+
+                    b.Property<int>("ReleaseDurationType");
+
+                    b.Property<int>("ReleaseStartType");
+
+                    b.Property<DateTime?>("ReleasedAt");
+
+                    b.Property<bool>("RunAlsoNormalTests");
+
+                    b.Property<bool>("ShouldAutomaticAssessSubmissions");
+
+                    b.Property<bool>("ShouldClearClipboard");
+
+                    b.Property<bool>("ShowAdditionalLogButton");
+
+                    b.HasKey("Id");
+
+                    b.HasAlternateKey("GeneratedCode")
+                        .HasName("Unique_GeneratedCode");
+
+                    b.HasIndex("ExerciseId");
+
+                    b.HasIndex("PLangId");
+
+                    b.ToTable("ExerciseReleases");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.CustomTestWithSingleSolutionAsTestResult", b =>
+                {
+                    b.Property<int>("CustomTestId");
+
+                    b.Property<int>("SolutionUserId");
+
+                    b.Property<int>("SolutionExerciseReleaseId");
+
+                    b.Property<int>("SolutionPLangId");
+
+                    b.Property<bool>("CharacterLimitExceeded");
+
+                    b.Property<int?>("CharacterLimitUsed");
+
+                    b.Property<int?>("CompileTimeoutInMsUsed");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<bool?>("HasCompiled");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<bool?>("Passed");
+
+                    b.Property<int?>("ProgramExitCode");
+
+                    b.Property<string>("Protocol")
+                        .HasMaxLength(160100);
+
+                    b.Property<string>("RunnerVersion")
+                        .HasMaxLength(2000);
+
+                    b.Property<int?>("TestResultCode");
+
+                    b.Property<string>("TestServerVersion")
+                        .HasMaxLength(2000);
+
+                    b.Property<int?>("TimeForCompiling");
+
+                    b.Property<int?>("TimeForUserProgram");
+
+                    b.Property<int?>("TimeoutInMsUsed");
+
+                    b.HasKey("CustomTestId", "SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId");
+
+                    b.HasIndex("CustomTestId");
+
+                    b.HasIndex("SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId");
+
+                    b.ToTable("CustomTestWithSingleSolutionAsTestResult");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.ExerciseReleaseWithUserAsParticipation", b =>
+                {
+                    b.Property<int>("UserId");
+
+                    b.Property<int>("ExerciseReleaseId");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("LastEditedPLangId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<bool>("LockSolutionsFlag");
+
+                    b.Property<bool>("ShouldNotCount");
+
+                    b.HasKey("UserId", "ExerciseReleaseId");
+
+                    b.HasIndex("ExerciseReleaseId");
+
+                    b.HasIndex("LastEditedPLangId");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("ExerciseReleaseWithUserAsParticipations");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.Solution", b =>
+                {
+                    b.Property<int>("UserId");
+
+                    b.Property<int>("ExerciseReleaseId");
+
+                    b.Property<int>("PLangId");
+
+                    b.Property<int?>("AssessmentId");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("LastEditingIpAddress")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int?>("MainFileId");
+
+                    b.Property<string>("Note")
+                        .HasMaxLength(10000);
+
+                    b.HasKey("UserId", "ExerciseReleaseId", "PLangId");
+
+                    b.HasIndex("AssessmentId")
+                        .IsUnique();
+
+                    b.HasIndex("MainFileId")
+                        .IsUnique();
+
+                    b.HasIndex("PLangId");
+
+                    b.HasIndex("UserId", "ExerciseReleaseId");
+
+                    b.ToTable("Solutions");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.SolutionAssessment", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("ExerciseReleaseId");
+
+                    b.Property<string>("FeedbackForStudent")
+                        .HasMaxLength(10000);
+
+                    b.Property<string>("LastAssessmentErrorMessage")
+                        .HasMaxLength(80000);
+
+                    b.Property<int?>("ManualPoints");
+
+                    b.Property<int>("MaxNormalTestPoints");
+
+                    b.Property<int>("MaxSubmitTestPoints");
+
+                    b.Property<int?>("NormalTestPoints");
+
+                    b.Property<string>("NoteForOtherTutors")
+                        .HasMaxLength(10000);
+
+                    b.Property<int>("PLangId");
+
+                    b.Property<int?>("SubmitTestPoints");
+
+                    b.Property<int>("UserId");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("SolutionAssessment");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.SolutionFile", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(70000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("DisplayIndex");
+
+                    b.Property<string>("FileNameWithExtension")
+                        .HasMaxLength(2000);
+
+                    b.Property<bool>("IsDisplayed");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("SolutionExerciseReleaseId");
+
+                    b.Property<int>("SolutionPLangId");
+
+                    b.Property<int>("SolutionUserId");
+
+                    b.Property<int?>("TemplateFileId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("TemplateFileId");
+
+                    b.HasIndex("SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId");
+
+                    b.ToTable("SolutionFiles");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.TestWithSingleSolutionAsTestResult", b =>
+                {
+                    b.Property<int>("TestId");
+
+                    b.Property<int>("SolutionUserId");
+
+                    b.Property<int>("SolutionExerciseReleaseId");
+
+                    b.Property<int>("SolutionPLangId");
+
+                    b.Property<bool>("CharacterLimitExceeded");
+
+                    b.Property<int?>("CharacterLimitUsed");
+
+                    b.Property<int?>("CompileTimeoutInMsUsed");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<bool?>("HasCompiled");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<bool?>("Passed");
+
+                    b.Property<int?>("ProgramExitCode");
+
+                    b.Property<string>("Protocol")
+                        .HasMaxLength(160100);
+
+                    b.Property<string>("RunnerVersion")
+                        .HasMaxLength(2000);
+
+                    b.Property<int?>("TestResultCode");
+
+                    b.Property<string>("TestServerVersion")
+                        .HasMaxLength(2000);
+
+                    b.Property<int?>("TimeForCompiling");
+
+                    b.Property<int?>("TimeForUserProgram");
+
+                    b.Property<int?>("TimeoutInMsUsed");
+
+                    b.HasKey("TestId", "SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId");
+
+                    b.HasIndex("TestId");
+
+                    b.HasIndex("SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId");
+
+                    b.ToTable("TestWithSingleSolutionAsTestResult");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tag", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("Description")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("HtmlBackgroundColor")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("HtmlColor")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("HtmlIcon")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("DisplayName")
+                        .HasName("Unique_Tag");
+
+                    b.ToTable("Tags");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.TagWithMetaData", b =>
+                {
+                    b.Property<int>("TagId");
+
+                    b.Property<int>("MetaDataId");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("TagId", "MetaDataId");
+
+                    b.HasIndex("MetaDataId");
+
+                    b.HasIndex("TagId");
+
+                    b.ToTable("TagWithMetaDatas");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.TemplateFile", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int?>("CodeTemplateId")
+                        .IsRequired();
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(70000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("DisplayIndex");
+
+                    b.Property<string>("FileNameWithExtension")
+                        .HasMaxLength(2000);
+
+                    b.Property<bool>("IsContentVisibleForUser");
+
+                    b.Property<bool>("IsEditableByUser");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CodeTemplateId");
+
+                    b.ToTable("TemplateFiles");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.CustomTest", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(80000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("DisplayIndex");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(2000);
+
+                    b.Property<int>("ExerciseReleaseId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("TestTypeId");
+
+                    b.Property<int>("UserId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("TestTypeId");
+
+                    b.HasIndex("UserId", "ExerciseReleaseId");
+
+                    b.ToTable("CustomTest");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.DefaultCustomTestSettings", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("CompileTimeoutInMs");
+
+                    b.Property<string>("CompilerOptions")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("ExerciseId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("MaxDiskSpaceInKb");
+
+                    b.Property<int>("MemoryLimitInKb");
+
+                    b.Property<int>("TimeoutInMs");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ExerciseId")
+                        .IsUnique();
+
+                    b.ToTable("DefaultCustomTestSettings");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.Test", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(80000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("DisplayIndex");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(2000);
+
+                    b.Property<int>("ExerciseId");
+
+                    b.Property<bool>("IsSubmitTest");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("TestSettingsId");
+
+                    b.Property<int>("TestTypeId");
+
+                    b.Property<int>("Weight");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ExerciseId");
+
+                    b.HasIndex("TestSettingsId")
+                        .IsUnique();
+
+                    b.HasIndex("TestTypeId");
+
+                    b.ToTable("Tests");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.TestSettings", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("CompileTimeoutInMs");
+
+                    b.Property<string>("CompilerOptions")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("MaxDiskSpaceInKb");
+
+                    b.Property<int>("MemoryLimitInKb");
+
+                    b.Property<int>("TestId");
+
+                    b.Property<int>("TimeoutInMs");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("TestCaseSettingses");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.TestType", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("InternalName")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("TestTypes");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.TestWithFileAsAssetReference", b =>
+                {
+                    b.Property<int>("TestId");
+
+                    b.Property<int>("FileReferenceTestAssetId");
+
+                    b.HasKey("TestId", "FileReferenceTestAssetId");
+
+                    b.HasIndex("FileReferenceTestAssetId");
+
+                    b.HasIndex("TestId");
+
+                    b.ToTable("TestWithFileAsAssetReferences");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Files.FileReferenceMarkdownAsset", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("Hash")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<string>("MimeType")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("OriginalName")
+                        .HasMaxLength(2000);
+
+                    b.Property<long>("SizeInBytes");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("FileReferenceMarkdownAssets");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Files.FileReferenceTestAsset", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("Hash")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<string>("MimeType")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("OriginalName")
+                        .HasMaxLength(2000);
+
+                    b.Property<long>("SizeInBytes");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("FileReferenceTestAssets");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Files.FileReferenceUserFileAsset", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("Hash")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<string>("MimeType")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("OriginalName")
+                        .HasMaxLength(2000);
+
+                    b.Property<long>("SizeInBytes");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("FileReferenceUserFileAssets");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Lang", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("LangShortcut")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("Language")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("Langs");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.PLang", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("EditorHighlightModeName")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("FileExtensionsWithDot")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("InternalName")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("PLangs");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.AuthToken", b =>
+                {
+                    b.Property<int>("UserId");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("CsrfToken")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("ExpirationDateTime");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<string>("RandomSecret")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("UserAuthToken")
+                        .HasMaxLength(2000);
+
+                    b.HasKey("UserId");
+
+                    b.HasIndex("UserAuthToken")
+                        .IsUnique();
+
+                    b.HasIndex("UserId")
+                        .IsUnique();
+
+                    b.ToTable("AuthTokens");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.ExternalUser", b =>
+                {
+                    b.Property<int>("ExternalId")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("Email")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("FirstName")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("LastName")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<bool>("NeedToRefreshData");
+
+                    b.Property<string>("Token")
+                        .IsRequired()
+                        .HasMaxLength(2000);
+
+                    b.Property<int>("UserId");
+
+                    b.HasKey("ExternalId");
+
+                    b.HasAlternateKey("Token")
+                        .HasName("Unique_ExternalToken");
+
+                    b.HasIndex("UserId")
+                        .IsUnique();
+
+                    b.ToTable("ExternalUsers");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.GroupRole", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(2000);
+
+                    b.Property<int>("GroupRolePermissionId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("GroupRolePermissionId")
+                        .IsUnique();
+
+                    b.ToTable("GroupRoles");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.GroupRolePermission", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<bool>("CanAddUserToGroup");
+
+                    b.Property<bool>("CanAssessExercises");
+
+                    b.Property<bool>("CanChangeExercises");
+
+                    b.Property<bool>("CanChangeGroupData");
+
+                    b.Property<bool>("CanChangeOtherMembersRole");
+
+                    b.Property<bool>("CanCreateExercises");
+
+                    b.Property<bool>("CanDeleteExercises");
+
+                    b.Property<bool>("CanLockExercisesPermanently");
+
+                    b.Property<bool>("CanManageExerciseReleases");
+
+                    b.Property<bool>("CanRemoveMemberFromGroup");
+
+                    b.Property<bool>("CanSeeExercisesFromOthersInGroup");
+
+                    b.Property<bool>("CanSeeOtherMembers");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("GroupRoleId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("GroupRolePermissions");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.Settings.CodeEditorSetting", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("FontSize");
+
+                    b.Property<bool>("HighlightCurrentLine");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<bool>("ShowInvisibles");
+
+                    b.Property<bool>("ShowLineIndentions");
+
+                    b.Property<bool>("ShowLineNumbers");
+
+                    b.Property<int>("TabSize");
+
+                    b.Property<string>("Theme")
+                        .HasMaxLength(2000);
+
+                    b.Property<bool>("UseWrapping");
+
+                    b.Property<int>("UserSettingId");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("CodeEditorSettings");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.Settings.UserSetting", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("CodeEditorSettingsId");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int?>("LangId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<string>("Theme")
+                        .HasMaxLength(2000);
+
+                    b.Property<int?>("UserId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CodeEditorSettingsId")
+                        .IsUnique();
+
+                    b.HasIndex("LangId");
+
+                    b.HasIndex("UserId")
+                        .IsUnique();
+
+                    b.ToTable("UserSettingses");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.SystemRole", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("Email")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("SystemRolePermissionId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("SystemRolePermissionId")
+                        .IsUnique();
+
+                    b.ToTable("SystemRoles");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.SystemRolePermission", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<bool>("CanChangeOtherUsersSystemRole");
+
+                    b.Property<bool>("CanChangeRoles");
+
+                    b.Property<bool>("CanChangeSystemSettings");
+
+                    b.Property<bool>("CanChangeUserData");
+
+                    b.Property<bool>("CanCreateGroups");
+
+                    b.Property<bool>("CanCreateRoles");
+
+                    b.Property<bool>("CanDeleteActivatedUsers");
+
+                    b.Property<bool>("CanDeleteGroups");
+
+                    b.Property<bool>("CanDeleteRoles");
+
+                    b.Property<bool>("CanManageNewUsers");
+
+                    b.Property<bool>("CanManageTags");
+
+                    b.Property<bool>("CanViewDashboard");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("SystemRoleId");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("SystemRolePermissions");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.SystemSetting", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("CurrentServerMessage")
+                        .HasMaxLength(10000);
+
+                    b.Property<int>("CustomProjectTestCompileTimeoutInMs");
+
+                    b.Property<int>("CustomProjectTestMaxDiskSpaceInKb");
+
+                    b.Property<int>("CustomProjectTestMemoryLimitInKb");
+
+                    b.Property<int>("CustomProjectTestTimeoutInMs");
+
+                    b.Property<int>("DefaultGroupCreatorGroupRoleId");
+
+                    b.Property<int>("DefaultGroupRoleId");
+
+                    b.Property<int>("DefaultUserGroupId");
+
+                    b.Property<int>("JustRunProgramCompileTimeoutInMs");
+
+                    b.Property<int>("JustRunProgramMaxDiskSpaceInKb");
+
+                    b.Property<int>("JustRunProgramMemoryLimitInKb");
+
+                    b.Property<int>("JustRunProgramTimeoutInMs");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("MaxCustomProjectsPerUser");
+
+                    b.Property<int>("MaxCustomTestsPerParticipation");
+
+                    b.Property<int>("MaxNumberOfTestsWithOneRequest");
+
+                    b.Property<int>("MaxNumberOfTestsWithOneRequestSubmitTestServer");
+
+                    b.Property<int>("SubmitTestServerTimeoutInMs");
+
+                    b.Property<string>("SubmitTestServerUrl")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("TestServerConfigUiUrl")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("TestServerStatsUrl")
+                        .HasMaxLength(2000);
+
+                    b.Property<int>("TestServerTimeoutInMs");
+
+                    b.Property<string>("TestServerUrl")
+                        .HasMaxLength(2000);
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("DefaultGroupCreatorGroupRoleId")
+                        .IsUnique();
+
+                    b.HasIndex("DefaultGroupRoleId")
+                        .IsUnique();
+
+                    b.HasIndex("DefaultUserGroupId")
+                        .IsUnique();
+
+                    b.ToTable("SystemSettings");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.User", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("Email")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("FirstName")
+                        .HasMaxLength(2000);
+
+                    b.Property<bool>("IsActivated");
+
+                    b.Property<DateTime>("LastLoginAt");
+
+                    b.Property<string>("LastName")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<string>("Password")
+                        .HasMaxLength(2000);
+
+                    b.Property<int?>("SystemRoleId");
+
+                    b.Property<string>("Token")
+                        .IsRequired()
+                        .HasMaxLength(2000);
+
+                    b.HasKey("Id");
+
+                    b.HasAlternateKey("Token")
+                        .HasName("Unique_Token");
+
+                    b.HasIndex("SystemRoleId");
+
+                    b.ToTable("Users");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.UserGroup", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(2000);
+
+                    b.Property<string>("Email")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("UserGroups");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.UserWithUserGroup", b =>
+                {
+                    b.Property<int>("UserId");
+
+                    b.Property<int>("UserGroupId");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("GroupRoleId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("UserId", "UserGroupId");
+
+                    b.HasIndex("GroupRoleId");
+
+                    b.HasIndex("UserGroupId");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("UserWithUserGroups");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProject", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.User", "User")
+                        .WithMany("CustomProjects")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectDescription", b =>
+                {
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProject", "CustomProject")
+                        .WithOne("Description")
+                        .HasForeignKey("ClientServer.Models.CustomProjects.CustomProjectDescription", "CustomProjectId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectDescriptionWithFileAsAssetReference", b =>
+                {
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProjectDescription", "CustomProjectDescription")
+                        .WithMany("AssetReferences")
+                        .HasForeignKey("CustomProjectDescriptionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Files.FileReferenceUserFileAsset", "FileReferenceUserFileAsset")
+                        .WithMany("CustomProjectDescriptionWithFileAsAssetReferences")
+                        .HasForeignKey("FileReferenceUserFileAssetId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectSolution", b =>
+                {
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProject", "CustomProject")
+                        .WithMany("Solutions")
+                        .HasForeignKey("CustomProjectId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProjectSolutionFile", "MainFile")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.CustomProjects.CustomProjectSolution", "MainFileId")
+                        .OnDelete(DeleteBehavior.SetNull);
+
+                    b.HasOne("ClientServer.Models.PLang", "PLang")
+                        .WithMany()
+                        .HasForeignKey("PLangId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectSolutionFile", b =>
+                {
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProjectSolution")
+                        .WithMany("SolutionFiles")
+                        .HasForeignKey("CustomProjectSolutionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTest", b =>
+                {
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProject", "CustomProject")
+                        .WithMany("Tests")
+                        .HasForeignKey("CustomProjectId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Tests.TestSettings", "TestSettings")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.CustomProjects.CustomProjectTest", "TestSettingsId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Tests.TestType", "TestType")
+                        .WithMany()
+                        .HasForeignKey("TestTypeId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTestWithFileAsAssetReference", b =>
+                {
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProjectTest", "CustomProjectTest")
+                        .WithMany("AssetReferences")
+                        .HasForeignKey("CustomProjectTestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Files.FileReferenceUserFileAsset", "FileReferenceUserFileAsset")
+                        .WithMany("CustomProjectTestWithFileAsAssetReferences")
+                        .HasForeignKey("FileReferenceUserFileAssetId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTestWithSolutionAsTestResult", b =>
+                {
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProjectSolution", "CustomProjectSolution")
+                        .WithMany("TestResults")
+                        .HasForeignKey("CustomProjectSolutionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProjectTest", "CustomProjectTest")
+                        .WithMany("TestResults")
+                        .HasForeignKey("CustomProjectTestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.AfterSolutions.AfterSolution", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.AfterSolutions.AfterSolutionFile", "MainFile")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Exercises.AfterSolutions.AfterSolution", "MainFileId")
+                        .OnDelete(DeleteBehavior.SetNull);
+
+                    b.HasOne("ClientServer.Models.Exercises.Solution.Solution", "Solution")
+                        .WithOne("AfterSolution")
+                        .HasForeignKey("ClientServer.Models.Exercises.AfterSolutions.AfterSolution", "SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.AfterSolutions.AfterSolutionFile", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.AfterSolutions.AfterSolution", "AfterSolution")
+                        .WithMany("SolutionFiles")
+                        .HasForeignKey("AfterSolutionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.TemplateFile", "TemplateFile")
+                        .WithMany()
+                        .HasForeignKey("TemplateFileId");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.AfterSolutions.CustomTestWithAfterSolutionAsTestResult", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.AfterSolutions.AfterSolution", "AfterSolution")
+                        .WithMany("CustomTestResults")
+                        .HasForeignKey("AfterSolutionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Tests.CustomTest", "CustomTest")
+                        .WithMany("AfterTestResults")
+                        .HasForeignKey("CustomTestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.AfterSolutions.TestWithAfterSolutionAsTestResult", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.AfterSolutions.AfterSolution", "AfterSolution")
+                        .WithMany("TestResults")
+                        .HasForeignKey("AfterSolutionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Tests.Test", "Test")
+                        .WithMany("AfterTestResults")
+                        .HasForeignKey("TestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.CodeTemplate", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Exercise", "Exercise")
+                        .WithMany("CodeTemplates")
+                        .HasForeignKey("ExerciseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.TemplateFile", "MainFile")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Exercises.CodeTemplate", "MainFileId")
+                        .OnDelete(DeleteBehavior.SetNull);
+
+                    b.HasOne("ClientServer.Models.PLang", "PLang")
+                        .WithMany()
+                        .HasForeignKey("PLangId");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.CustomTestWithFileAsAssetReference", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Tests.CustomTest", "CustomTest")
+                        .WithMany("AssetReferences")
+                        .HasForeignKey("CustomTestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Files.FileReferenceUserFileAsset", "FileReferenceUserFileAsset")
+                        .WithMany("CustomTestWithFileAsAssetReferences")
+                        .HasForeignKey("FileReferenceUserFileAssetId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Exercise", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.UserGroup", "UserGroup")
+                        .WithMany("Exercises")
+                        .HasForeignKey("UserGroupId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Users.User", "User")
+                        .WithMany("Exercises")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.SetNull);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.ExerciseDescription", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Exercise", "Exercise")
+                        .WithOne("Description")
+                        .HasForeignKey("ClientServer.Models.Exercises.ExerciseDescription", "ExerciseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.ExerciseDescriptionWithFileAsAssetReference", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.ExerciseDescription", "ExerciseDescription")
+                        .WithMany("AssetReferences")
+                        .HasForeignKey("ExerciseDescriptionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Files.FileReferenceMarkdownAsset", "FileReferenceMarkdownAsset")
+                        .WithMany("AssetReferences")
+                        .HasForeignKey("FileReferenceMarkdownAssetId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.MetaData", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Exercise", "Exercise")
+                        .WithOne("MetaData")
+                        .HasForeignKey("ClientServer.Models.Exercises.MetaData", "ExerciseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Release.ExerciseRelease", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Exercise", "Exercise")
+                        .WithMany("Releases")
+                        .HasForeignKey("ExerciseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.PLang", "PLang")
+                        .WithMany()
+                        .HasForeignKey("PLangId");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.CustomTestWithSingleSolutionAsTestResult", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Tests.CustomTest", "CustomTest")
+                        .WithMany("TestResultsNew")
+                        .HasForeignKey("CustomTestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Solution.Solution", "Solution")
+                        .WithMany("CustomTestResults")
+                        .HasForeignKey("SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.ExerciseReleaseWithUserAsParticipation", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Release.ExerciseRelease", "ExerciseRelease")
+                        .WithMany("ExerciseReleaseWithUserAsParticipations")
+                        .HasForeignKey("ExerciseReleaseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.PLang", "LastEditedPLang")
+                        .WithMany()
+                        .HasForeignKey("LastEditedPLangId");
+
+                    b.HasOne("ClientServer.Models.Users.User", "User")
+                        .WithMany("ExerciseReleaseWithUserAsParticipations")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.Solution", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Solution.SolutionAssessment", "Assessment")
+                        .WithOne("Solution")
+                        .HasForeignKey("ClientServer.Models.Exercises.Solution.Solution", "AssessmentId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Solution.SolutionFile", "MainFile")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Exercises.Solution.Solution", "MainFileId")
+                        .OnDelete(DeleteBehavior.SetNull);
+
+                    b.HasOne("ClientServer.Models.PLang", "PLang")
+                        .WithMany()
+                        .HasForeignKey("PLangId");
+
+                    b.HasOne("ClientServer.Models.Exercises.Solution.ExerciseReleaseWithUserAsParticipation", "ExerciseReleaseWithUserAsParticipation")
+                        .WithMany("Solutions")
+                        .HasForeignKey("UserId", "ExerciseReleaseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.SolutionFile", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.TemplateFile", "TemplateFile")
+                        .WithMany("SolutionParts")
+                        .HasForeignKey("TemplateFileId")
+                        .OnDelete(DeleteBehavior.SetNull);
+
+                    b.HasOne("ClientServer.Models.Exercises.Solution.Solution", "Solution")
+                        .WithMany("SolutionFiles")
+                        .HasForeignKey("SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.TestWithSingleSolutionAsTestResult", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Tests.Test", "Test")
+                        .WithMany("TestResultsNew")
+                        .HasForeignKey("TestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Solution.Solution", "Solution")
+                        .WithMany("TestResults")
+                        .HasForeignKey("SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.TagWithMetaData", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.MetaData", "MetaData")
+                        .WithMany("TagWithMetaDatas")
+                        .HasForeignKey("MetaDataId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Tag", "Tag")
+                        .WithMany()
+                        .HasForeignKey("TagId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.TemplateFile", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.CodeTemplate")
+                        .WithMany("TemplateFiles")
+                        .HasForeignKey("CodeTemplateId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.CustomTest", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Tests.TestType", "TestType")
+                        .WithMany()
+                        .HasForeignKey("TestTypeId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Solution.ExerciseReleaseWithUserAsParticipation")
+                        .WithMany("CustomTests")
+                        .HasForeignKey("UserId", "ExerciseReleaseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.DefaultCustomTestSettings", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Exercise", "Exercise")
+                        .WithOne("DefaultCustomTestSettings")
+                        .HasForeignKey("ClientServer.Models.Exercises.Tests.DefaultCustomTestSettings", "ExerciseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.Test", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Exercise", "Exercise")
+                        .WithMany("Tests")
+                        .HasForeignKey("ExerciseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Tests.TestSettings", "TestSettings")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Exercises.Tests.Test", "TestSettingsId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Tests.TestType", "TestType")
+                        .WithMany()
+                        .HasForeignKey("TestTypeId");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.TestWithFileAsAssetReference", b =>
+                {
+                    b.HasOne("ClientServer.Models.Files.FileReferenceTestAsset", "FileReferenceTestAsset")
+                        .WithMany("AssetReferences")
+                        .HasForeignKey("FileReferenceTestAssetId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Tests.Test", "Test")
+                        .WithMany("AssetReferences")
+                        .HasForeignKey("TestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.AuthToken", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.User", "User")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Users.AuthToken", "UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.ExternalUser", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.User", "User")
+                        .WithOne("ExternalUser")
+                        .HasForeignKey("ClientServer.Models.Users.ExternalUser", "UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.GroupRole", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.GroupRolePermission", "GroupRolePermission")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Users.GroupRole", "GroupRolePermissionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.Settings.UserSetting", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.Settings.CodeEditorSetting", "CodeEditorSetting")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Users.Settings.UserSetting", "CodeEditorSettingsId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Lang", "Lang")
+                        .WithMany()
+                        .HasForeignKey("LangId")
+                        .OnDelete(DeleteBehavior.SetNull);
+
+                    b.HasOne("ClientServer.Models.Users.User", "User")
+                        .WithOne("UserSettings")
+                        .HasForeignKey("ClientServer.Models.Users.Settings.UserSetting", "UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.SystemRole", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.SystemRolePermission", "SystemRolePermission")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Users.SystemRole", "SystemRolePermissionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.SystemSetting", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.GroupRole", "DefaultGroupCreatorGroupRole")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Users.SystemSetting", "DefaultGroupCreatorGroupRoleId");
+
+                    b.HasOne("ClientServer.Models.Users.GroupRole", "DefaultGroupRole")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Users.SystemSetting", "DefaultGroupRoleId");
+
+                    b.HasOne("ClientServer.Models.Users.UserGroup", "DefaultUserGroup")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Users.SystemSetting", "DefaultUserGroupId");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.User", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.SystemRole", "SystemRole")
+                        .WithMany()
+                        .HasForeignKey("SystemRoleId")
+                        .OnDelete(DeleteBehavior.SetNull);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.UserWithUserGroup", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.GroupRole", "GroupRole")
+                        .WithMany("UserUserGroups")
+                        .HasForeignKey("GroupRoleId");
+
+                    b.HasOne("ClientServer.Models.Users.UserGroup", "UserGroup")
+                        .WithMany("UserWithUserGroups")
+                        .HasForeignKey("UserGroupId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Users.User", "User")
+                        .WithMany("UserWithUserGroups")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+        }
+    }
+}
diff --git a/src/ClientServer/Migrations/20190801144540_addFakeFksToOtherSides.cs b/src/ClientServer/Migrations/20190801144540_addFakeFksToOtherSides.cs
new file mode 100755
index 0000000..431e5d6
--- /dev/null
+++ b/src/ClientServer/Migrations/20190801144540_addFakeFksToOtherSides.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace ClientServer.Migrations
+{
+    public partial class addFakeFksToOtherSides : Migration
+    {
+        
+        //actually we want to drop the foreign key constraint to on delete no action
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.CreateTable(
+                name: "CustomProjectTestSettings",
+                columns: table => new
+                {
+                    Id = table.Column<int>(nullable: false)
+                        .Annotation("Npgsql:ValueGeneratedOnAdd", true),
+                    CompileTimeoutInMs = table.Column<int>(nullable: false),
+                    CompilerOptions = table.Column<string>(maxLength: 2000, nullable: true),
+                    CreatedAt = table.Column<DateTime>(nullable: false),
+                    CustomProjectTestId = table.Column<int>(nullable: false),
+                    LastUpdatedAt = table.Column<DateTime>(nullable: false),
+                    MaxDiskSpaceInKb = table.Column<int>(nullable: false),
+                    MemoryLimitInKb = table.Column<int>(nullable: false),
+                    TimeoutInMs = table.Column<int>(nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_CustomProjectTestSettings", x => x.Id);
+                });
+
+            migrationBuilder.AddColumn<int>(
+                name: "SystemRoleId",
+                table: "SystemRolePermissions",
+                nullable: false,
+                defaultValue: 0);
+
+            migrationBuilder.AddColumn<int>(
+                name: "UserSettingId",
+                table: "CodeEditorSettings",
+                nullable: false,
+                defaultValue: 0);
+
+            migrationBuilder.AddColumn<int>(
+                name: "GroupRoleId",
+                table: "GroupRolePermissions",
+                nullable: false,
+                defaultValue: 0);
+
+            migrationBuilder.AddColumn<int>(
+                name: "TestId",
+                table: "TestCaseSettingses",
+                nullable: false,
+                defaultValue: 0);
+
+            migrationBuilder.AddColumn<int>(
+                name: "ExerciseReleaseId",
+                table: "SolutionAssessment",
+                nullable: false,
+                defaultValue: 0);
+
+            migrationBuilder.AddColumn<int>(
+                name: "PLangId",
+                table: "SolutionAssessment",
+                nullable: false,
+                defaultValue: 0);
+
+            migrationBuilder.AddColumn<int>(
+                name: "UserId",
+                table: "SolutionAssessment",
+                nullable: false,
+                defaultValue: 0);
+            
+        }
+
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropColumn(
+                name: "SystemRoleId",
+                table: "SystemRolePermissions");
+
+            migrationBuilder.DropColumn(
+                name: "UserSettingId",
+                table: "CodeEditorSettings");
+
+            migrationBuilder.DropColumn(
+                name: "GroupRoleId",
+                table: "GroupRolePermissions");
+
+            migrationBuilder.DropColumn(
+                name: "TestId",
+                table: "TestCaseSettingses");
+
+            migrationBuilder.DropColumn(
+                name: "ExerciseReleaseId",
+                table: "SolutionAssessment");
+
+            migrationBuilder.DropColumn(
+                name: "PLangId",
+                table: "SolutionAssessment");
+
+            migrationBuilder.DropColumn(
+                name: "UserId",
+                table: "SolutionAssessment");
+
+            migrationBuilder.DropTable(
+                name: "CustomProjectTestSettings");
+        }
+    }
+}
diff --git a/src/ClientServer/Migrations/YapexDbContextModelSnapshot.cs b/src/ClientServer/Migrations/YapexDbContextModelSnapshot.cs
index fee1131..295dacc 100755
--- a/src/ClientServer/Migrations/YapexDbContextModelSnapshot.cs
+++ b/src/ClientServer/Migrations/YapexDbContextModelSnapshot.cs
@@ -204,6 +204,33 @@ namespace ClientServer.Migrations
                     b.ToTable("CustomProjectTestAssets");
                 });
 
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTestSettings", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("CompileTimeoutInMs");
+
+                    b.Property<string>("CompilerOptions")
+                        .HasMaxLength(2000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("CustomProjectTestId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("MaxDiskSpaceInKb");
+
+                    b.Property<int>("MemoryLimitInKb");
+
+                    b.Property<int>("TimeoutInMs");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("CustomProjectTestSettings");
+                });
+
             modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTestWithFileAsAssetReference", b =>
                 {
                     b.Property<int>("CustomProjectTestId");
@@ -755,6 +782,8 @@ namespace ClientServer.Migrations
                     b.Property<int>("Id")
                         .ValueGeneratedOnAdd();
 
+                    b.Property<int>("ExerciseReleaseId");
+
                     b.Property<string>("FeedbackForStudent")
                         .HasMaxLength(10000);
 
@@ -772,8 +801,12 @@ namespace ClientServer.Migrations
                     b.Property<string>("NoteForOtherTutors")
                         .HasMaxLength(10000);
 
+                    b.Property<int>("PLangId");
+
                     b.Property<int?>("SubmitTestPoints");
 
+                    b.Property<int>("UserId");
+
                     b.HasKey("Id");
 
                     b.ToTable("SolutionAssessment");
@@ -1068,6 +1101,8 @@ namespace ClientServer.Migrations
 
                     b.Property<int>("MemoryLimitInKb");
 
+                    b.Property<int>("TestId");
+
                     b.Property<int>("TimeoutInMs");
 
                     b.HasKey("Id");
@@ -1351,6 +1386,8 @@ namespace ClientServer.Migrations
 
                     b.Property<DateTime>("CreatedAt");
 
+                    b.Property<int>("GroupRoleId");
+
                     b.Property<DateTime>("LastUpdatedAt");
 
                     b.HasKey("Id");
@@ -1384,6 +1421,8 @@ namespace ClientServer.Migrations
 
                     b.Property<bool>("UseWrapping");
 
+                    b.Property<int>("UserSettingId");
+
                     b.HasKey("Id");
 
                     b.ToTable("CodeEditorSettings");
@@ -1478,6 +1517,8 @@ namespace ClientServer.Migrations
 
                     b.Property<DateTime>("LastUpdatedAt");
 
+                    b.Property<int>("SystemRoleId");
+
                     b.HasKey("Id");
 
                     b.ToTable("SystemRolePermissions");
diff --git a/src/ClientServer/Models/CustomProjects/CustomProjectTestSettings.cs b/src/ClientServer/Models/CustomProjects/CustomProjectTestSettings.cs
new file mode 100644
index 0000000..78d54e3
--- /dev/null
+++ b/src/ClientServer/Models/CustomProjects/CustomProjectTestSettings.cs
@@ -0,0 +1,42 @@
+using System.ComponentModel.DataAnnotations;
+using ClientServer.Db;
+using ClientServer.Models.Exercises.Tests;
+using ClientServer.Models.Interfaces;
+
+namespace ClientServer.Models.CustomProjects
+{
+    public class CustomProjectTestSettings : ITestSettings
+    {
+        public int Id { get; set; }
+
+        /// <summary>
+        /// the timeout in ms
+        /// </summary>
+        public int TimeoutInMs { get; set; }
+
+        /// <summary>
+        /// the compile timeout in ms
+        /// </summary>
+        public int CompileTimeoutInMs { get; set; }
+
+        /// <summary>
+        /// the max amount of ram in mb for the <see cref="Test"/>
+        /// </summary>
+        public int MemoryLimitInKb { get; set; }
+
+        /// <summary>
+        /// the max amount of disk space the <see cref="Test"/> can write to
+        /// </summary>
+        public int MaxDiskSpaceInKb { get; set; }
+
+        /// <summary>
+        /// some compiler options .g. -Xlint options needs to be separated by whitespaces (like normal command args)
+        /// </summary>
+        [MaxLength(YapexDbContext.DefaultMaxStringLength)]
+        public string CompilerOptions { get; set; }
+        
+        //fk
+        public int CustomProjectTestId { get; set; }
+//        public CustomProjectTest CustomProjectTest { get; set; }
+    }
+}
diff --git a/src/ClientServer/Models/Exercises/Solution/SolutionAssessment.cs b/src/ClientServer/Models/Exercises/Solution/SolutionAssessment.cs
index 6dfb963..c6149f4 100644
--- a/src/ClientServer/Models/Exercises/Solution/SolutionAssessment.cs
+++ b/src/ClientServer/Models/Exercises/Solution/SolutionAssessment.cs
@@ -60,6 +60,10 @@ namespace ClientServer.Models.Exercises.Solution
         [MaxLength(YapexDbContext.NotesMaxStringLength)]
         public string FeedbackForStudent { get; set; }
 
+        //fks of solution
+        public int PLangId { get; set; }
+        public int UserId { get; set; }
+        public int ExerciseReleaseId { get; set; }
         /// <summary>
         /// the connected <see cref="Solution"/>
         /// </summary>
@@ -72,6 +76,7 @@ namespace ClientServer.Models.Exercises.Solution
 //        /// always the latest version is used (normally) or null if the user did not submit something
 //        /// </summary>
 //        public SolutionVersion SolutionVersion { get; set; }
+        
 
     }
 }
diff --git a/src/ClientServer/Models/Exercises/Tests/TestSettings.cs b/src/ClientServer/Models/Exercises/Tests/TestSettings.cs
index 8972147..2c84115 100644
--- a/src/ClientServer/Models/Exercises/Tests/TestSettings.cs
+++ b/src/ClientServer/Models/Exercises/Tests/TestSettings.cs
@@ -1,5 +1,6 @@
 using System.ComponentModel.DataAnnotations;
 using ClientServer.Db;
+using ClientServer.Models.CustomProjects;
 using ClientServer.Models.Interfaces;
 
 namespace ClientServer.Models.Exercises.Tests
@@ -36,5 +37,10 @@ namespace ClientServer.Models.Exercises.Tests
         /// </summary>
         [MaxLength(YapexDbContext.DefaultMaxStringLength)]
         public string CompilerOptions { get; set; }
+        
+        //fk
+        public int TestId { get; set; }
+//        public Test Test { get; set; }
+
     }
 }
diff --git a/src/ClientServer/Models/Users/GroupRolePermission.cs b/src/ClientServer/Models/Users/GroupRolePermission.cs
index 88b9c43..fc76ce4 100644
--- a/src/ClientServer/Models/Users/GroupRolePermission.cs
+++ b/src/ClientServer/Models/Users/GroupRolePermission.cs
@@ -100,5 +100,9 @@ namespace ClientServer.Models.Users
         /// false: not
         /// </summary>
         public bool CanChangeGroupData { get; set; }
+
+        //fk
+        public int GroupRoleId { get; set; }
+//        public GroupRole GroupRole { get; set; }
     }
 }
diff --git a/src/ClientServer/Models/Users/Settings/CodeEditorSettings.cs b/src/ClientServer/Models/Users/Settings/CodeEditorSettings.cs
index 3238a93..46a35b9 100644
--- a/src/ClientServer/Models/Users/Settings/CodeEditorSettings.cs
+++ b/src/ClientServer/Models/Users/Settings/CodeEditorSettings.cs
@@ -44,5 +44,9 @@ namespace ClientServer.Models.Users.Settings
         /// </summary>
         public bool UseWrapping { get; set; }
 
+        //fk
+        public int UserSettingId { get; set; }
+//        public UserSetting UserSetting { get; set; }
+
     }
 }
diff --git a/src/ClientServer/Models/Users/SystemRolePermission.cs b/src/ClientServer/Models/Users/SystemRolePermission.cs
index b9df0a6..e8554f9 100644
--- a/src/ClientServer/Models/Users/SystemRolePermission.cs
+++ b/src/ClientServer/Models/Users/SystemRolePermission.cs
@@ -77,5 +77,9 @@ namespace ClientServer.Models.Users
         /// </summary>
         public bool CanViewDashboard { get; set; }
 
+        //fk
+        public int SystemRoleId { get; set; }
+//        public SystemRole SystemRole { get; set; }
+
     }
 }
-- 
GitLab