簡體   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