修复“Data is Null. This method or 属性 cannot be called on Null values” 不使用数据注释,

fix " Data is Null. This method or property cannot be called on Null values " without using data annotations ,

我正在尝试使用 entity framework 从数据库中检索数据,我有 table 个具有许多属性的“帖子”,其中一个属性是“图像”,图像 属性 是以前不需要,所以我在“帖子”table 中存储了很多记录,“图像”的值为 null,现在我将“图像”更改为必需,现在尝试从“帖子”检索旧记录时 table asp.net 启动此异常(“数据为 Null。无法对 Null 值调用此方法或 属性”)。

我需要什么: 我知道我可以通过从“图像”属性 中删除删除 [required] 注释来解决此问题,但我想保留此数据注释并检索所有记录天气“图像”值为 Null 或不为 Null。

有什么办法吗?

我的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace ARID.Models
{
public class Post
{
    [Key]
    public Guid Id { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "طول العنوان يجب ان يتراوح بين 25 حرف و 100 حرف", MinimumLength = 25)]
    [Display(Name ="العنوان")]
    public string Title { get; set; }

    [Required]
    [StringLength(5000, ErrorMessage = "يجب ألا يتجاوز المحتوى عن 900 كلمة ولايقل عن 50 كلمة", MinimumLength = 50)]
   
          [Display(Name = "المحتوى")]
    public string Body { get; set; }

    [Display(Name = "تاريخ النشر")]
    [DataType(DataType.DateTime)]
    [DisplayFormat(DataFormatString = "{0:d}")]
    public DateTime DateTime { get; set; }

    [Display(Name = "السماح بالتعليقات")]
    public bool IsCommentsAllowed { get; set; }

    [StringLength(100)]
    [Display(Name = "الصورة")]
    [Required]
    public string Image { get; set; }

    [StringLength(100)]
    [Display(Name = "الملف المرفق")]
    public string File { get; set; }

    [Display(Name = "تمت الموافقة")]
    public bool IsApproved { get; set; }

    [Display(Name = "اخفاء المنشور")]
    public bool IsHidden { get; set; }

    [Display(Name = "مميز")]
    public bool IsFeatured { get; set; }

    [Display(Name = "هدية لافضل اجابة")]
    public bool IsGifted { get; set; }

    [Display(Name = "نوع الهدية")]
    public GiftType GiftType { get; set; }

    [Display(Name = "عدد القراء")]
    public int Reads { get; set; }

    [Display(Name = "حذف المنشور")]
    public bool IsDeleted { get; set; }

    [Display(Name = "المجتمع")]
    public int CommunityId { get; set; }
    [Display(Name = "المجتمع")]
    public  Community Community { get; set; }

    [Display(Name = "الناشر")]
    [StringLength(450)]
    public string ApplicationUserId { get; set; }
    [Display(Name = "الناشر")]
    public  ApplicationUser ApplicationUser { get; set; }

    [StringLength(100, ErrorMessage = "الكلمات المفتاحية قصيرة", MinimumLength = 5)]
    //[Required(ErrorMessage = "حقل الكلمات المفتاحية ضروري")]
    [Display(Name = "كلمات مفتاحية")]
    public string Tags { get; set; }

          [Display(Name = "نوع المنشور")]
    public GroupPostType PostType { get; set; }

    [Display(Name = "طلب النشر في مدونة منصة اريد")]
    public bool IsPublishRequest { get; set; }

    [Display(Name = "حالة طلب النشر")]
    public bool PublishRequestStatus { get; set; }

}

}

在控制器中:

 public async Task<JsonResult> GetWallContents()
    {
        ARIDWallViewModel WallVM = new ARIDWallViewModel()
        {
            Posts = _context.Posts.Include(a => a.Community).Include(a => a.ApplicationUser).Where(a => a.Community.CommunityType == CommunityType.Personal && !a.IsHidden).OrderByDescending(a => a.DateTime).Take(25),
            PostComments = _context.PostComments.Include(a => a.ApplicationUser).Include(a => a.Post).OrderByDescending(a => a.DateTime).Take(25),
            Publications = _context.Publications.Include(a => a.ApplicationUser).OrderByDescending(a => a.DateOfRecord).Take(25),

            Courses = _context.Courses.Include(a=>a.ApplicationUser).OrderByDescending(a => a.DateOfRecord).Take(25),
            FreelancerReadyServices = _context.FreelancerReadyServices.Include(c => c.ApplicationUser).OrderByDescending(a => a.DateOfRecord).Take(25),
            Books = _context.Book.Include(c => c.ApplicationUser).Where(c => c.IsARIDPublications == true && c.IsFeatured == true).OrderByDescending(a => a.RecordDate).Take(25),
        };
        //ViewData["Count"] = _context.PostMetric.Count(a => a.PostId == id);
        return Json(WallVM);
    }

简短的回答是:不,你不能。

在您的数据库中已经有没有设置图像 属性 的条目,现在您已将其更改为必需的,因此根据新规则,您现有的条目不再有效。因此 EF 无法检索它们,因为它只是遵循您为模型设置的规则 - 此外,将 属性 标记为必需(和 non-nullable)将是糟糕的编码风格,然后在现有条目仍然为空(您甚至不会收到这些空引用的编译器警告,因为您的字符串被标记为不可空)。

因此,您必须通过迁移修复现有条目(您可能在添加所需属性后没有创建条目,否则 EF 会生成一个迁移,将数据库中的列更改为“non-nullable “这会因为现有行包含 null 而失败 - 这就是为什么即使在对模型进行微小更改后也应该始终生成迁移的原因)。只需创建一个迁移并将现有条目的 Image 属性 设置为默认值。

如果您不想修改现有条目,那么您可能别无选择,只能从 Image 属性 中删除 required 属性(因为 属性 如果某些实例不提供值,则不是真正需要的)并通过将 Image 的 setter 设为私有并添加一个 UpdateImage 方法来验证自己对新条目的验证新图像不为空并设置 属性.