DataContext.SubmitChanges() 每次我想更新连接的数据库时都会抛出 NullReferenceException

DataContext.SubmitChanges() throws NullReferenceException everytime I want to update connected database

提问人:Marcin Sobolewski 提问时间:7/5/2018 最后编辑:Marcin Sobolewski 更新时间:7/5/2018 访问量:91

问:

正如我在主题标题中所说,我对 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)上加入用户。简单地说 - 当 User.staffId == Administrator.adminId AND User.role = “ADM” 时,我知道表 Users 中的 User 是管理员。

那么探针在哪里呢? 我为这个数据库制作了 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); }
    }}

当然,这两个类都有构造函数,但我没有把它粘贴到这里(当我必须这样做时,我会这样做)。

所以在上面你可以看到,我是如何将表和关系从数据库映射到对象的。

问题是当我尝试使用表 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

提前感谢所有试图帮助我的人,我将不胜感激! 编辑:我只是忘了提到,我认为以这种方式制作和映射的数据库可能效果很好,因为当我的应用程序启动时,我正在创建新的数据库作为程序的公共字段(应用程序根目录)并使用它,我给用户一个登录的可能性,什么可以完美(在登录步骤中,我们必须检查来自用户和例如管理员的数据)。

C# SQL-Server NullReferenceException) DataContext SubmitChanges

评论

0赞 jdweng 7/5/2018
使用 SQL 命令生成器。一个 SQL 命令有 4 个查询:Select、Update、Delete、Insert。命令生成器采用 Select 查询并创建其他三个查询。提交更改需要所有四个查询。
0赞 Marcin Sobolewski 7/7/2018
感谢您的回答,这个解决方案对我有很大帮助,现在效果很好!当我一直在寻找问题的解决方案时,我看到了 SqlCommand 的使用,但我只是想知道,是否有可能使用 LINQ 方式来执行更新和例如插入,因为正如我所说,select 效果很好。换句话说,我只是想知道,是否有一种方法可以在不编写 SQL 命令的情况下执行 CRUD 操作。无论如何,谢谢你的帮助!

答: 暂无答案