2012-06-25 22 views
5

Tôi đã tìm kiếm câu trả lời cho điều này trong 2 ngày nay. Tôi thậm chí không chắc chắn chính xác những gì là sai, nhưng tôi nghĩ rằng tôi có thể đã xác định chính xác thủ phạm có thể.Lỗi xác thực cơ sở dữ liệu. Cho phép giá trị nullable trong một bảng nhưng không có trong bảng có liên quan (chuẩn hóa)

Chương trình của tôi là trình theo dõi/quản lý cơ sở dữ liệu sẽ theo dõi thiết bị tại công ty của tôi. Người dùng có thể truy vấn, tạo và chỉnh sửa thiết bị. Ngay bây giờ, truy vấn cơ sở dữ liệu hoạt động, nhưng khi tôi cố gắng thêm vào hoặc cập nhật cơ sở dữ liệu, chương trình sẽ ném lỗi xác thực (tôi sẽ đi sâu vào vấn đề này bên dưới).

Tôi có một lớp thiết bị có nhiều thuộc tính không có giá trị (vì người dùng có thể không biết nhiều thuộc tính này khi tạo mục nhập mới, chúng tôi đã để lại gần như tất cả các thuộc tính có thể null) và được kết nối với (sử dụng khóa ngoài và tải chậm/"ảo") vào một vài bảng khác đã được thực hiện để giúp bình thường hóa cơ sở dữ liệu.

Dưới đây là một số mã abreviated để giúp:

Thiết bị mẫu:

public class Equipment 
{ 
    public int EquipmentId { get; set; } //required 

    public string Company { get; set; } //required 

    public bool Verified { get; set; } //required 

    (...other non-required attributes...) 


    //The following two attributes are where my problems are I believe 
    [ForeignKey("PAU")] 
    public int PAUId { get; set; } //required and Foreign Key  

    //This is not required (but is FK to the related table) if the user doesn't know 
    [ForeignKey("Division")] 
    public Nullable<int> DivisionId { get; set; } 


    //These are the lazy loading connections to the other tables in the database 

    public virtual Division Division { get; set; } 

    public virtual PAU PAU { get; set; } 
} 

Division mẫu: Bảng này chỉ chứa 5 bộ phận khác nhau tại công ty chúng tôi và các ID liên quan.

public class Division 
{ 
    public Division() 
    { 
     this.Equipments = new HashSet<Equipment>(); 
    } 

    //These are non-nullable/required fields 
    public int DivisionId { get; set; } 
    public string DivisionName { get; set; } 

    public virtual ICollection<Equipment> Equipments { get; set; } 
} 

PAU Model: Mô hình này chứa PAU # s và mô tả và ID liên quan.

public class PAU 
{ 
    public PAU() 
    { 
     this.Equipments = new HashSet<Equipment>(); 
    } 

    //These are non-nullable/required fields 
    public int PAUId { get; set; } 
    public string PAUNumber { get; set; } 
    public string PAUDescription { get; set; } 

    public virtual ICollection<Equipment> Equipments { get; set; } 
} 

điều khiển thiết bị:

public class EquipmentController : Controller 
{ 
    TLCP_DEVEntities4 db = new TLCP_DEVEntities4(); 

    (...) 

    public ActionResult Edit(int id)   
    { 
     ViewData["divisions"] = new SelectList(db.Equipments. 
           OrderBy(x => x.Division.DivisionName). 
           Select(x => x.Division).ToList(). 
           Distinct(), "DivisionId", "DivisionName"); 

     ViewData["PAUNumbers"] = new SelectList(db.Equipments. 
           OrderBy(x => x.PAU.PAUNumber). 
           Select(x => x.PAU).ToList(). 
           Distinct(), "PAUId", "PAUNumber"); 

     return View(db.Equipments.Find(id)); 
    } 

    [HttpPost] 
    public ActionResult Edit(Equipment equipment) 
    { 
     if (ModelState.IsValid) 
     { 
      db.Entry(equipment).State = EntityState.Modified;      
      db.SaveChanges();  //fails here          
      return RedirectToAction("Maintenance"); 
     } 

     ViewData["divisions"] = new SelectList(db.Equipments. 
           OrderBy(x => x.Division.DivisionName). 
           Select(x => x.Division).ToList(). 
           Distinct(), "DivisionId", "DivisionName"); 

     ViewData["PAUNumbers"] = new SelectList(db.Equipments. 
           OrderBy(x => x.PAU.PAUNumber). 
           Select(x => x.PAU).ToList(). 
           Distinct(), "PAUId", "PAUNumber"); 

     return View(equipment); 
    } 

    public ActionResult AddEquipment() 
    { 
     ViewData["divisions"] = new SelectList(db.Equipments. 
           OrderBy(x => x.Division.DivisionName). 
           Select(x => x.Division).ToList(). 
           Distinct(), "DivisionId", "DivisionName"); 

     ViewData["PAUNumbers"] = new SelectList(db.Equipments. 
           OrderBy(x => x.PAU.PAUNumber). 
           Select(x => x.PAU).ToList(). 
           Distinct(), "PAUId", "PAUNumber"); 

     return View(); 
    } 

    public ActionResult AddEquipment(Equipment equipment) 
    { 
     try 
     { 
      db.Equipments.Add(equipment); 
      db.SaveChanges(); 

      return RedirectToAction("Maintenance"); 
     } 
     catch (Exception ex) 
     { 

      ViewData["divisions"] = new SelectList(db.Equipments. 
            OrderBy(x => x.Division.DivisionName). 
            Select(x => x.Division).ToList(). 
            Distinct(), "DivisionId", "DivisionName"); 

      ViewData["PAUNumbers"] = new SelectList(db.Equipments. 
           OrderBy(x => x.PAU.PAUNumber). 
           Select(x => x.PAU).ToList(). 
           Distinct(), "PAUId", "PAUNumber"); 

      return View(); 
     } 
    } 

    (...) 
} 

Trong quan điểm tôi có danh sách thả xuống cho các thuộc tính được dân cư với các tùy chọn có thể đã có trong cơ sở dữ liệu (lưu trữ trong ViewData ở trên). Tôi đã thử một vài cách khác nhau để lưu trữ dữ liệu này vào mô hình của tôi, nhưng cách này dường như làm việc tốt nhất:

<%: Html.DropDownListFor(model => model.DivisionId, 
     ViewData["divisions"] as SelectList, "")%> 

Ok như vậy sau khi rất nhiều gỡ lỗi, các vấn đề có vẻ là vì các thuộc tính lười nạp có các thuộc tính không được phép trong bảng của chúng. Ví dụ của tôi sẽ được giải quyết nhiều hơn với việc tạo ra các đối tượng thiết bị mới, mặc dù tôi tin rằng vấn đề là như nhau để chỉnh sửa chúng.

Ví dụ phân chia: Vì vậy, DivisionId trong lớp Thiết bị có thể là rỗng (người dùng không biết hoặc thiết bị không thuộc bộ phận cụ thể) và bảng/lớp Thiết bị không phàn nàn về điều đó. Nhưng khi tôi cố gắng SaveChanges(), chương trình than phiền bởi vì đối tượng Division ảo là null (có DivisionId mặc định là 0 và một DivisionName null). Vì Device.DivisionId là null, tôi không muốn cập nhật bảng Division cho đối tượng Device này. Có cách nào để giải quyết vấn đề này không? Tôi có nên lười biếng không?

PAU Ví dụ: Vì PAUId là thuộc tính bắt buộc cho tất cả đối tượng Thiết bị, nhưng như trong Ví dụ về bộ phận, PAU.PAUNumber và PAU.PAUDescription là null (và PAU.PAUId là mặc định 0) gây ra lỗi. Điều này giống như cái đầu tiên, nhưng với thuộc tính bắt buộc (vì vậy tôi không chắc chắn nó có cần phải được xử lý khác nhau) hay không.

Vì vậy, tôi không thực sự chắc chắn cách khắc phục sự cố này.

  • Bạn có đang tải vấn đề này vì tôi chỉ muốn kết nối đối tượng Thiết bị với các bảng khác nếu Id/Khóa ngoại không rỗng?

  • Có phương pháp nào tôi có thể gọi để cập nhật giá trị của đối tượng thiết bị từ các bảng khác dựa trên Id không? Đó có phải là một phương pháp mà tôi cần để tạo ra bản thân mình?

  • Nếu tôi loại bỏ tải chậm, bạn có thể giải thích cách tôi nên viết truy vấn của mình để tôi vẫn có thể truy cập vào dữ liệu chuẩn hóa (như DivisionName) không?

Tôi xin lỗi vì bài đăng dài. Tôi chỉ không muốn bỏ lỡ bất cứ điều gì có thể quan trọng.

Sửa

tôi có một giải pháp thô đến PAU Ví dụ (nhưng tôi không nghĩ rằng nó làm việc cho Bộ phận Ví dụ vì cho phép null trong Thiết bị nhưng không phải là bảng cá nhân).

public ActionResult AddEquipment(Equipment equipment) 
    { 
     try 
     { 
      equipment.PAU.PAUId = equipment.PAUId; 
      equipment.PAU.PAUNumber = db.PAUs.Find(equipment.PAUId).PAUNumber; 
      equipment.PAU.PAUDescription = db.PAUs.Find(equipment.PAUId).PAUDescription; 


     (...) 

    } 

Nó không phải là rất thanh lịch mặc dù. Tôi đã thử nhìn vào một hướng dẫn về sự phản chiếu, nhưng nó không thực sự có ý nghĩa. Nếu đó sẽ là một giải pháp thanh lịch hơn, ai đó có thể thử giải thích điều đó?

Tôi vẫn đang tìm giải pháp cho Ví dụ phân chia (vì Equipment.DivisionId không có giá trị nhưng Division.DivisionId không có giá trị này không hoạt động), vì vậy bất kỳ trợ giúp nào về giải pháp này hoặc giải pháp thanh lịch hơn ở trên sẽ được đánh giá rất nhiều!

+0

Và đây là lỗi tôi nhận được (nó không phải là rất hữu ích và khi tôi đã tìm kiếm trên này tôi đã không tìm thấy một câu trả lời mà cố định nó): {System.Data.Entity.Validation.DbEntityValidationException: Xác nhận không thành công cho một hoặc nhiều thực thể hơn. Xem thuộc tính 'EntityValidationErrors' để biết thêm chi tiết. tại System.Data.Entity.Internal.InternalContext.SaveChanges() tại System.Data.Entity.Internal.LazyInternalContext.SaveChanges() tại System.Data.Entity.DbContext.SaveChanges() tại DLMP_Asset_Tracking.Controllers.EquipmentController .AddEquipment (Thiết bị thiết bị) –

+0

Có gì trong thuộc tính 'EntityValidationErrors'? –

+0

Nó cho thấy PAUId = 0 (mặc định, phải?), Và PAUDescription và PAUNumber là null (giống với Division và 4 thuộc tính khác mà tôi đã bỏ qua câu hỏi do dự phòng). Mảng ValidationErrors cho thấy rằng các thuộc tính null (PAUNumber và PAUDescription) là bắt buộc, chúng là do cách tôi thiết lập các bảng cơ sở dữ liệu. Điều đó có trả lời câu hỏi của bạn không George? –

Trả lời

0

Có một phần khác của mã của tôi đã hoạt động kỳ lạ gây ra lỗi. Tôi đánh giá cao tất cả sự giúp đỡ của bạn! Cảm ơn!

Các vấn đề liên quan