DataContext.SubmitChanges () генерирует исключение NullReferenceException каждый раз, когда я хочу обновить подключенную базу данных - PullRequest
0 голосов
/ 04 июля 2018

Как я уже сказал в заголовке темы, у меня проблема с методом DataContext.SubmitChanges (). У меня есть две таблицы: пользователи и администраторы (и другие роли, как доктора и т. Д., Но сейчас я работаю с этими двумя таблицами). SQL-скрипты для этих двух таблиц: Пользователи:

`CREATE TABLE [dbo].[Users](
    [usrId] [int] IDENTITY(1,1) NOT NULL,
    [login] [nvarchar](50) NOT NULL,
    [password] [nvarchar](50) NOT NULL,
    [role] [char](3) NOT NULL,
    [staffId] [int] NOT NULL,
 CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED 
(
    [usrId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]`

А для администраторов:

`CREATE TABLE [dbo].[Administrators](
    [adminId] [int] IDENTITY(1,1) NOT NULL,
    [name] [nvarchar](50) NOT NULL,
    [surname] [nvarchar](50) NOT NULL,
 CONSTRAINT [PK_Administrators] PRIMARY KEY CLUSTERED 
(
    [adminId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]`

Теперь администраторы присоединяются к пользователям по адресу Administrators.adminId = Users.staffId (adminId - PK, staffId - FK). Просто - я знаю, что пользователь из таблицы Users является администратором, когда User.staffId == Administrator.adminId AND User.role = "ADM".

Так где же пробм? Я сделал отображение LINQ для этой базы данных:

[Database(Name = "BD_PROJ_GKiO3")]
public class BD_PROJ_GKiO3 : DataContext
{
    public Table<User> Users;
    public Table<Doctor> Doctors;
    public Table<LaboratoryWorker> LaboratoryWorkers;
    public Table<LaboratoryManager> LaboratoryManagers;
    public Table<Registrator> Registrators;
    public Table<Administrator> Administrators;
    public Table<Appointment> Appointments;
    public Table<ExaminationType> ExaminationTypes;
    public Table<LaboratoryExamination> LaboratoryExaminations;
    public Table<Patient> Patients;
    public Table<PhysicalExamination> PhysicalExaminations;

    public BD_PROJ_GKiO3(IDbConnection connection) : base(connection)
    {

    }
}

И отображение для пользователя и администратора:

[Table(Name = "Users")]
public class User
{
    //kolumna PK w tabeli Users
    [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "Int NOT NULL IDENTITY")]
    public int usrId { get; set; }

    //Reszta kolumn
    [Column] public string login { get; set; }
    [Column] public string password { get; set; }
    [Column] public string role { get; set; }
    [Column] public string status { get; set; }
    [Column] public int staffId { get; set; }

    //Mapowanie relacji z tabelami aktorów
    private EntitySet<Doctor> _Doctors;
    [Association(Storage = "_Doctors", OtherKey = "docId", ThisKey = "staffId")]
    public EntitySet<Doctor> Doctors
    {
        get { return this._Doctors; }
        set { this._Doctors.Assign(value); }
    }

    private EntitySet<Registrator> _Registrators;
    [Association(Storage = "_Registrators", OtherKey = "registratorId", ThisKey = "staffId")]
    public EntitySet<Registrator> Registrators
    {
        get { return this._Registrators; }
        set { this._Registrators.Assign(value); }
    }

    private EntitySet<Administrator> _Administrators;
    [Association(Storage = "_Administrators", OtherKey = "adminId", ThisKey = "staffId", IsForeignKey = true)]
    public EntitySet<Administrator> Administrators
    {
        get { return this._Administrators; }
        set { this._Administrators.Assign(value); }
    }

    private EntitySet<LaboratoryManager> _LaboratoryManagers;
    [Association(Storage = "_LaboratoryManagers", OtherKey = "laboratoryPrincipalId", ThisKey = "staffId")]
    public EntitySet<LaboratoryManager> LaboratoryManagers
    {
        get { return this._LaboratoryManagers; }
        set { this._LaboratoryManagers.Assign(value); }
    }

    private EntitySet<LaboratoryWorker> _LaboratoryWorkers;
    [Association(Storage = "_LaboratoryWorkers", OtherKey = "laboratoryWorkerId", ThisKey = "staffId")]
    public EntitySet<LaboratoryWorker> LaboratoryWorkers
    {
        get { return this._LaboratoryWorkers; }
        set { this._LaboratoryWorkers.Assign(value); }
    }}


[Table(Name = "Administrators")]
public class Administrator
{
    //PK w tabeli Administrators
    [Column(IsPrimaryKey = true, IsDbGenerated = true)]
    public int adminId { get; set; }

    //Reszta kolumn
    [Column] public string name { get; set; }
    [Column] public string surname { get; set; }

    //Mapowanie relacji tabeli Administrators z tabelą Users
    private EntitySet<User> _Users;
    [Association(Storage = "_Users", OtherKey = "staffId", IsForeignKey = true, ThisKey = "adminId")]
    public EntitySet<User> Users
    {
        get { return this._Users; }
        set { this._Users.Assign(value); }
    }}

Конечно, у обоих классов есть конструкторы, но я здесь их не вставлял (когда мне придется, я сделаю это).

Итак, выше вы можете видеть, как я отображал таблицы и отношения из базы данных в объекты.

Проблема в том, что я пытаюсь обновить существующую строку в таблице Users с помощью связанной строки в таблице Administrators. Я создал экземпляр пользователя (toUpdate), в котором хранятся данные, с помощью которых должна обновляться строка таблицы, затем я добавляю к ней данные экземпляров администратора (admin). Сначала - я получаю объект DataContext, затем - ищу базу данных, чтобы мой пользователь мог ее редактировать.

как первый:

BD_PROJ_GKiO3 newDB = new BD_PROJ_GKiO3(Program.getConnection());
            User u = newDB.Users.SingleOrDefault(us => us.usrId == currentlyEdited.usrId);

Найден правильный пользователь (u), поэтому я пытаюсь выполнить код ниже:

                            u.login = toUpdate.login;
                            u.role = toUpdate.role;
                            u.status = toUpdate.status;
                            u.staffId = toUpdate.staffId;
                            u.Administrators.ElementAt(0).name = admin.name;
                            u.Administrators.ElementAt(0).surname = admin.surname;
                            newDB.SubmitChanges();

И при выполнении последней строки (newDB.SubmitChanges ()) выбрасывается исключение NullReferenceException.

Трассировка стека: ExceptionStackTrace

Заранее спасибо всем, кто попытается мне помочь, буду очень благодарен! Редактировать: я просто забыл упомянуть, что я думаю, что база данных, созданная и отображенная таким образом, вероятно, работает хорошо, потому что, когда мое приложение запускается, я создаю новую базу данных как общедоступное поле программы (корень приложения) и, используя ее, я даю У пользователя есть возможность войти, что работает отлично (при входе в систему мы должны проверить данные от пользователей и, например, от администраторов).

...