实体框架验证上下文 - 空测试中的空异常

本文关键字:测试 异常 框架 验证 上下文 实体 | 更新日期: 2023-09-27 17:57:06

我正在研究PC配置器应用程序,我在验证时遇到问题。应用程序的重点是检查主板上的插槽是否与CPU等的插槽相同。

我在Visual Studio 2013中使用脚手架制作了代码优先数据库。

public class Configuration : IValidatableObject
{
    [Key]
    public int ConfigurationID { get; set; }
    [Required]
    [StringLength(50, MinimumLength = 3)]
    [DisplayName("Configuration name")]
    public string ConfigName { get; set; }
    [ForeignKey("mb_id")]
    public MotherBoard MotherBoard { get; set; }
    [Column("mb_id", TypeName = "int")]
    public Nullable<int> mb_id { get; set; }
    [ForeignKey("cpu_id")]
    public CPU CPU { get; set; }
    [Column("cpu_id", TypeName = "int")]
    public Nullable<int> cpu_id { get; set; }
}

这是我正在使用的配置模型的一部分(其余部分看起来非常相似 - 只是其他组件)

我只是把这个模型脚手架到控制器中。

这是验证的开始,似乎问题出在这里的某个地方(至少 VS 是这么说的)。

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    if (MotherBoard == null) { throw new ArgumentNullException("Motherboard"); }
    if (CPU == null) { throw new ArgumentNullException("CPU"); }
    if (GPU == null) { throw new ArgumentNullException("GPU"); }
    if (HDD == null) { throw new ArgumentNullException("HDD"); }
    if (RAM == null) { throw new ArgumentNullException("RAM"); }
    if (Power == null) { throw new ArgumentNullException("Power"); }
    if (Case == null) { throw new ArgumentNullException("Case"); }
    if (MotherBoard.CPU.ToUpper().Trim() != CPU.Socket.ToUpper().Trim())
    {
            yield return new ValidationResult("CPU socket does not match.", new[] { "cpu_id" });
    }
}

当我在没有验证的情况下创建PC配置时,它通常会进入数据库。但是当我尝试此验证时,它说 CPU(在空测试中)为空并抛出空异常。截图来自VS。

它永远不会把它扔到主板上,而是总是扔在下一项(第二项)上。

实体框架验证上下文 - 空测试中的空异常

CPU 似乎被实体框架视为导航属性。 如果没有更多信息,这表明您需要:

  1. using System.Data.Entity以任何单位选择型号
  2. 从数据库枚举查询之前.Include(c => c.CPU)

如果这确实是一个导航属性,则可能会延迟加载,如实体框架材料中所述。

这意味着,即使这些值似乎存在于数据库中,实际集合(或在您的情况下为引用)在内存中也将为 null。 因此,我们告诉实体框架在获取时"包含"这些项目:

var configuration = db.ConfigurationsOrSomething
    .Include(c => c.CPU)
    .Where(c => c.DeletedOrWhatever == false)
    .ToList();
var cpu = configuration.CPU;
if(cpu == null)
    Debug.WriteLine("Something else is the problem. :(");

确实说过您已经在数据库中看到了该值。 我们看不到您用于从数据库中选择实体的代码 - 或者其他任何内容(如果有其他内容)。 我们还可以看到 CPU 是您定义和引用的另一种类型。 您的模型看起来像 EF Code First/Table-per Type,如果您需要了解它以及辅导

注意:我以新的眼光重新阅读了您的评论。 当您被问及它是否进入数据库时,您同意它是"正常创建"的,未经验证。

我现在认为您的整个设置是一个简单的验证失败。 如果验证显示 CPU 为空...则 CPU 为空。

那么:用于创建Configuration实体的新实例的代码在哪里? 您是否只是没有为 CPU 分配值?