繁体   English   中英

Microsoft.EntityFrameworkCore.DbUpdateException:'保存实体更改时出错。 SqlException:列名“UsersUserID”无效

[英]Microsoft.EntityFrameworkCore.DbUpdateException: 'An error occurred while saving the entity changes. SqlException: Invalid column name 'UsersUserID'

当我尝试将记录添加到我的数据库时遇到问题。 视图正在注册,尝试添加到秘书/学生时,_db.SaveChanges() 上发生以下错误。

SqlException:列名“UsersUserID”无效。

错误(1)的屏幕截图 错误截图(2)

我手动添加了对迁移/迁移快照的更改,并删除了用户用户 ID 列,因为它与 FK 用户 ID 重复。 我尝试搜索该列,但没有出现。 删除迁移并创建新数据库也不能解决问题。 有谁知道如何解决这个问题?

这是我的用户 Model。

public class Users
    {
        [Key]
        public int UserID { get; set; }

        [Required]
        public string Name { get; set; }

        [Required]
        public string Surname { get; set; }        
        
        public string Password { get; set; }
        
        public string Email { get; set; }

        public string AddressLine1 { get; set; }

        public string AddressLine2 { get; set; }

        public int SuburbID { get; set; }

        public string Title { get; set; }

        public int RoleID { get; set; }  

        public string ErrorMessage { get; set; }

        public virtual ICollection<Secretaries> Secretaries { get; set; }
        public virtual ICollection<Student> Student { get; set; }

        public virtual Suburb Suburb { get; set; }

        public virtual Role Role { get; set; }
    }

这是我的学生 Model

public class Student
    {
        [Key]
        public int StudentID { get; set; }

        public int UserID { get; set; }

        [Required]
        public DateTime DateJoined { get; set; } = DateTime.Now;

        [StringLength(1)]
        [Required]
        public char Is_Active { get; set; } = 'T';

        public virtual Users Users { get; set; }
    }

这是我的秘书 model

public class Secretaries
    {
        [Key]
        public int SecretaryID { get; set; }

        public int UserID { get; set; }

        [Required]
        public DateTime DateJoined { get; set; } = DateTime.Now;

        [StringLength(1)]
        [Required]
        public char Is_Active { get; set; } = 'T';

        public virtual Users Users { get; set; }
    }

这是我收到错误的部分

public IActionResult Registration(Users users)
        {

            try
            {
                //users.Role.RoleID;
                _db.Users.Add(users);
                
                //_db.SaveChanges();
                int role = users.RoleID;
                int id = users.UserID;               

                if (role == 1)
                {
                    Student student= new Student();

                    student.UserID = id;

                    _db.Student.Add(student);
                    _db.SaveChanges();
                }
                else if (role == 2)
                {
                    Secretaries secretary = new Secretaries();

                    secretary.UserID = id;                    
                    
                    _db.Secretaries.Add(secretary);
                    _db.SaveChanges();
                }           

                return RedirectToAction("Index", "Home");
            }
            catch
            {
                return View(users);
            }
        }

首先,命名约定将有助于避免实体的复数形式丢失。 “用户”意味着多个,并且您的命名与“学生”不一致。 EF 可以管理诸如具有名为“Users”的表名和名为“User”的实体的详细信息。 在最坏的情况下,如果存在命名问题,您可以使用[Table("Users")]属性。 实体可以使用有意义的名称,即使它与表的名称不匹配。

您可能遇到的问题是,虽然 EF 可以按照约定自动解析实体和 FK 等事物之间的某些关系,但除非您严格遵循已知约定,否则 EF 可能会遗漏一些需要您提供它们的细节。 就我个人而言,我选择保持配置相当谨慎和一致,而不是依赖惯例和在它不起作用时偶尔出现的惊喜。 在您的情况下,两个可能的问题是将用户与他们声明的 FK 结婚,然后是双向映射。

使用名为“Users”的实体和属性,EF 可能无法按照约定将其与 UserId 匹配,充其量它可能正在寻找“UsersId”,因此当它没有发现它会寻找 TableNamePKName 所以“UsersUserID”其中“Users”是表名,“UserID”是该表中的 PK。 要解决这个问题:

[ForeignKey("UserID")]
public virtual Users Users { get; set; }

这告诉 EF 在哪里查找。 如果这是 C# 的更高版本,则:

[ForeignKey(nameof(UserID))]

...如果可以的话,避免使用魔法字符串。

下一个可能会影响映射的细节将是双向引用,其中一个秘书有一个用户,而用户有一个秘书的集合。 应避免双向引用,除非它们具有非常明确和有用的目的。 在大多数情况下,它们是不需要的,但是在你做它们的地方,它有助于声明关系的反面:

[ForeignKey("UserID")]
[InverseProperty("Secretaries")]
public virtual Users Users { get; set; }

这告诉 EF 期望用户实体上有一个名为“Secretaries”的导航属性,该属性将通过此用户引用进行链接。

双向引用可能会导致问题并在更新实体时需要更多注意,尤其是当您有执行序列化实体之类的代码时。 通常不需要它们,因为您通常可以从关系的一侧查询数据。

例如,要获取与给定用户关联的所有秘书,您可能认为您需要以下内容:

var user = context.Users.Include(u => u.Secretaries).Single(u => u.UserID == userId);
var secretaries = user.Secretaries;

...相反,您可以使用:

var secretaries = context.Secretaries.Where(s => s.User.UserID == userId).ToList(); // or (s => s.UserID == userId) where the UserID FK is exposed.

根据关联的目的,inheritance 可能更好地为您的架构提供服务,其中秘书/学生与用户的关系不是“具有”关系,而是“是”关系。 用户是否“拥有”秘书/学生,或者用户“是”秘书还是学生? 或者,“学生”与“秘书”是否更像是用户可以担任的“角色”? (这适合一个用户可能既是学生又是秘书的情况)

使用您当前定义的模式,它将允许一个用户潜在地与许多学生以及许多秘书相关联,这可能是也可能不是所需和预期的用途。 (也称为多对一关系)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM