【问题标题】:Invalid Column Name Entity guessing a foreign key that isn't there无效的列名实体猜测不存在的外键
【发布时间】:2014-12-10 02:06:00
【问题描述】:

我真的不明白这里发生了什么。根据我的研究,我收集到该实体正在尝试猜测外键的名称,但它不存在,因此它引发了“列名无效”错误。问题是有问题的模型/表没有任何外键。所以我真的很困惑。

这是引发错误的代码:

foreach (TechnologyProjectPlanModel result in results)
{
    //get approvers for plan
    int id = result.Id;

    try
    {
         List<ApprovalModel> approvers = db.ApprovalModels.Where(m => m.FormId == result.Id).Select(m => m).ToList();   //ERROR HERE

         if (approvers != null)
         {
             result.Approvers = approvers.ToList();
         }
    }
    catch (Exception e)
    { 
    }
}

这是ApprovalModel

public class ApprovalModel
{
    [Key]
    public int Id { get; set; }

    public int ApprovalProcessId { get; set; }
    public int FormId { get; set; }
    public int UserId { get; set; }
    public bool? Approved { get; set; }
}

这是 foreach 循环中引用的TechnologyProjectPlanModel

public class TechnologyProjectPlanModel
{
    [Key]
    public int Id { get; set; }

    public int FormId { get; set; }
    public int UserId { get; set; }
    public string FormType { get; set; }
    public int Status { get; set; }
    public int Hidden { get; set; }
    public DateTime DateSubmitted { get; set; }
    public DateTime DateFinalized { get; set; }

    public List<QuoteUploadsModel> Quotes { get; set; }
    public List<ApprovalModel> Approvers { get; set; }

    [Required]
    [Display(Name = "Please Select Your School")]
    public string School { get; set; }

    [Required]
    [Display(Name = "Requestor")]
    public string Requestor { get; set; }

    [Display(Name = "Title")]
    public string Title { get; set; }

    [Required]
    [DataType(DataType.PhoneNumber)]
    [Display(Name = "Phone Number")]
    [Phone]
    public string PhoneNumber { get; set; }

    [Required]
    [DataType(DataType.EmailAddress)]
    [Display(Name = "Email Address")]
    [EmailAddress]
    public string Email { get; set; }

    [Required]
    [Display(Name = "Project Title")]
    public string ProjectTitle { get; set; }

    [Display(Name = "Requested Completion Date")]
    public DateTime RequestedCompletionDate { get; set; }

    [Required]
    [Display(Name = "Project Description")]
    public string ProjectDescription { get; set; }

    [Display(Name = "Teacher/Room Number")]
    public string TeacherGroup { get; set; }

    [Display(Name = "1")]
    public bool Grade1 { get; set; }
    [Display(Name = "2")]
    public bool Grade2 { get; set; }
    [Display(Name = "3")]
    public bool Grade3 { get; set; }
    [Display(Name = "4")]
    public bool Grade4 { get; set; }
    [Display(Name = "5")]
    public bool Grade5 { get; set; }
    [Display(Name = "6")]
    public bool Grade6 { get; set; }
    [Display(Name = "7")]
    public bool Grade7 { get; set; }
    [Display(Name = "8")]
    public bool Grade8 { get; set; }
    [Display(Name = "9")]
    public bool Grade9 { get; set; }
    [Display(Name = "10")]
    public bool Grade10 { get; set; }
    [Display(Name = "11")]
    public bool Grade11 { get; set; }
    [Display(Name = "12")]
    public bool Grade12 { get; set; }
    [Display(Name = "Kindergarten")]
    public bool Kindergarten { get; set; }

    [Display(Name = "Describe how this plan will be continued if events cause programs or equipment to no longer be available.  For example, if equipment purchased needs repair what funding source will be used for repair or replacement?  For programs that have annual subscription fees, what funds will be used to continue the program from year to year?")]
    public string Sustainability { get; set; }

    public bool MultipleFundingSource { get; set; }

    [Required(ErrorMessage="*")]     
    [Display(Name = "Funding Source")]
    public string FundingSource1 { get; set; }

    [Required(ErrorMessage = "*")]
    public string FundingSource2 { get; set; }

    [Required(ErrorMessage = "*")]
    public string FundingSource3 { get; set; }

    [Required(ErrorMessage = "*")]
    public string FundingSource4 { get; set; }

    [Required(ErrorMessage = "*")]
    public string FundingSource5 { get; set; }

    [Required]
    [Display(Name = "Total Estimated Project Costs:")]
    public float TotalEstimatedProjectCosts { get; set; }

    //----------------------Additional Information

    [Display(Name = "Additional Comments:")]
    public string AdditionalComments { get; set; }

    [Display(Name = "Additional Supporting Documents:")]
    public string AdditionalSupportingDocuments { get; set; }
}

确切的错误是:

执行命令定义时出错。有关详细信息,请参阅内部异常。

内部异常:

列名“TechnologyProjectPlanModel_Id”无效。

我的代码中的任何地方都没有引用该列名,所以它一定是从某些东西中推断出来的。

有什么想法吗?谢谢!

【问题讨论】:

  • 当您执行以下任一操作时会发生什么: 1) 删除 .Select(m =&gt; m)(因为它是多余的)。 2) 在 Where 子句中使用 m.FormId == id
  • 这两项更改仍然相同
  • 您说ApprovalModel 没有外键。但是,它在TechnologyProjectPlanModelpublic List&lt;ApprovalModel&gt; Approvers { get; set; } 上被列为导航属性;它肯定应该有一个 FK,除非 EF 模型和你的 SQL 不一致。

标签: linq entity-framework


【解决方案1】:

实体框架依赖于约定来确定它认为您的数据库是什么样的。在这种情况下,它认为ApprovalModel 表应该具有TechnologyProjectPlanModel 表的外键。将您的实体缩小到相关字段,很明显为什么它会这样认为:

public class ApprovalModel
{
}

public class TechnologyProjectPlanModel
{
    public List<ApprovalModel> Approvers { get; set; }
}

在数据库术语中,为了使每个TechnologyProjectPlanModel 存在多个ApprovalModel,最有可能存在的关系是ApprovalModel 具有指向TechnologyProjectPlanModel 的外键。

TechnologyProjectPlanModel.Approvers 是如何设置的?如果它与实体框架没有任何关系,并且您不希望它尝试通过其约定填充此属性,您可以通过告诉它属性未像这样映射来明确告诉它不要做出该假设:

[NotMapped]
public List<ApprovalModel> Approvers { get; set; }

如果您确实有这种关系,则需要为 EF 提供更多上下文,以免它做出最佳猜测假设。例如,如果外键 确实 存在,请将其与相关的导航属性一起放在ApprovalModel 中,以便进一步告诉 EF 您的数据库是什么样的:

public class ApprovalModel
{
    public int TechnologyProjectPlanModelId { get; set; }

    // ForeignKey attribute usually not necessary unless you need to tell EF
    // about a property that doesn't follow the usual "{OtherEntityName}Id"
    // naming convention.
    [ForeignKey("TechnologyProjectPlanModelId")]
    public TechnologyProjectPlanModel TechnologyProjectPlanModel { get; set; }
}

public class TechnologyProjectPlanModel
{
    public List<ApprovalModel> Approvers { get; set; }
}

【讨论】:

  • 啊,非常感谢。我想出了另一种解决方法,但是 [NotMapped] 会快得多,谢谢!那么实体是否假设模型的任何集合都是导航属性?
  • 所有假设均基于约定类,此处详细描述:msdn.microsoft.com/en-us/library/…
【解决方案2】:

您知道,如果您正确执行映射,则不需要该代码块,因为 EF 会为您检索结果。审批者。

您可以直接在模型上使用基于属性的映射,也可以使用Code First Configuration to map your foreign key properly

一旦您正确映射了外键,您粘贴的代码块就不需要了,EF 会为您加载。

【讨论】:

  • 这就是我最终要做的。我想手动执行它只是为了避免循环引用,因为它被序列化为 JSON,但我继续为此制作了一个视图模型。不过感谢您的链接,应该对前进有很大帮助!
  • 是的,Ayende 有一篇关于该主题的帖子,投影到 ViewModel 绝对是避免该问题的方法。
猜你喜欢
  • 1970-01-01
  • 2015-04-10
  • 2022-08-21
  • 1970-01-01
  • 1970-01-01
  • 2014-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多