Что не так с моей Entity Framework и архитектурой? - PullRequest
1 голос
/ 09 октября 2019

Я занимаюсь разработкой веб-приложения для отслеживания задач, и вы можете увидеть полный код здесь: https://github.com/KimSergey94/TaskTracker

Короче говоря, администратор, менеджер, клиент и сотрудник являются пользователями приложения, а администратор является боссомэти роли. Чтобы проиллюстрировать это, менеджер может создать задачу, полученную клиентом, и назначить ее сотруднику. Задача включает в себя статусы и статусы включает в себя комментарии. «Роли» имеют идентификатор пользователя в качестве внешнего ключа к таблице «Пользователь», в которой хранятся их адреса электронной почты и пароли. В таблице ролей хранятся идентификаторы пользователей, чтобы у них были правильные роли.

Мне нужно разработать базовую функциональность, использовать некоторые из AJAX, пользовательские фильтры, хранимые процедуры. Что-то не так с моей логикой авторизации и ролей. Итак, я был бы признателен, если бы вы посмотрели и сообщили мне обо всем, что, по вашему мнению, неправильно.

В настоящее время, когда я пытаюсь запустить приложение и инициализировать базу данных, я получаю следующую ошибку:

System.Data.SqlClient.SqlException: 'Введение ограничения FOREIGN KEY' FK_dbo.Employees_dbo.Users_UserId 'в таблице' Сотрудники 'может вызывать циклы или несколько каскадных путей. Укажите ON DELETE NO ACTION или ON UPDATE NO ACTION, либо измените другие ограничения FOREIGN KEY.

Код классов пользователя и сотрудника:

public class User
    {
        public int UserId { get; set; }
        [DataType(DataType.EmailAddress)]
        [Required]
        public string Email { get; set; }
        public string Password { get; set; }
        public int RoleId { get; set; }

    }
public class Employee
    {
        public int EmployeeId { get; set; }


        //[Required(ErrorMessage = "First Name is required")]
        public string FirstName { get; set; }


        //[Required(ErrorMessage = "Last Name is required")]
        public string LastName { get; set; }

        //[Required(ErrorMessage = "Country field is required")]
        public string Country { get; set; }

        public string Position { get; set; }
        public int Salary { get; set; }

        public int UserId { get; set; }
        [ForeignKey("UserId")]
        public virtual User User { get; set; }

        //public virtual ICollection<Task> Tasks { get; set; }
    }

Globals.asax

protected void Application_Start()
{
    System.Data.Entity.Database.SetInitializer<TaskTrackerContext>(new TaskTrackerDbInitializer());

    var db = new TaskTrackerContext("TaskTrackerContext");
    db.Database.Initialize(true);

    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    ModelValidatorProviders.Providers.Clear();

    NinjectModule orderModule = new OrderModule();
    NinjectModule serviceModule = new ServiceModule("TaskTrackerDb");
    var kernel = new StandardKernel(orderModule, serviceModule);
    DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
}

web.config:

<connectionStrings>
    <add name="TaskTrackerContext" 
         connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename='|DataDirectory|\TaskTrackerContext.mdf';MultipleActiveResultSets=True; Integrated Security=True" 
         providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    <!--
    Initial Catalog=FormsAuth;

</appSettings>

Кстати, зачем мне это нужно Initial Catalog=FormsAuth;?

Я заметил, что с этим параметром я не смог создать экземпляр базы данных. Я хочу получить функциональность Включить для моих моделей

Ответы [ 2 ]

1 голос
/ 10 октября 2019

В EF Core вы должны отключить каскадное удаление с помощью DeleteBehavior.Restrict или DeleteBehavior.SetNull, например, в классе контекста базы данных введите новый метод

protected override void OnModelCreating(ModelBuilder modelBuilder){ 
   modelBuilder.HasOne(x => x.Employee).WithMany().HasForeignKey(x => 
   x.UserId).OnDelete(DeleteBehavior.Restrict) 
}

Если вы хотите каскадное поведение, вам нужноЧтобы добавить в UserId целое число, допускающее обнуляемость:

public int? UserId { get; set; }

Initial Catalog=FormsAuth; относится к пространству имен System.Web.Security и используется для проверки форм, вы можете прочитать об этом в Microsoft Docs: https://docs.microsoft.com/en-us/dotnet/api/system.web.security.formsauthentication?view=netframework-4.8

Я рекомендую использовать идентификацию asp.net, я вижу, что вы делаете заново изобретаете колесо, тогда как asp.net выполняет аутентификацию и проверку для вас. Вы можете прочитать об этом здесь: https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-3.0&tabs=visual-studio

0 голосов
/ 10 октября 2019

У меня была таблица, которая имела круговые отношения с другими, и я получал ту же ошибку. Оказывается, речь идет о внешнем ключе, который не обнулялся. Если ключ не имеет значения NULL, связанный объект должен быть удален, а циклические отношения не позволяют этого. Поэтому используйте обнуляемый внешний ключ.

public int? UserId { get; }
 [ForeignKey("UserId")]
public virtual User User { get; set; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...