【发布时间】:2016-01-27 00:07:52
【问题描述】:
我正在尝试使用 Entity Framework 6.1.3 创建“数据库中的代码优先”类,但似乎 E.F. 无法建立关联(或者我只是没有在我的数据库中正确设置某些内容)。
这是有问题的两个表,我正在使用实体框架制作类;
在我的数据库中,CVE 与 AssessmentChecks 是一对多的关系。因此,AssessmentChecks 表中有一个外键;
ALTER TABLE NVD.[AssessmentChecks] ADD CONSTRAINT
FK_AssessmentChecks_CVE FOREIGN KEY
(
CveIDFK
) REFERENCES NVD.CVE
(
CveID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
但是,当我从该数据库创建类时,Entity Framework 将“CveIDFK”标记为必填字段...
public partial class AssessmentCheck
{
public int AssessmentCheckID { get; set; }
[Required]
[StringLength(20)]
public string CveIDFK { get; set; }
public string AssessmentCheckSystem { get; set; }
public string AssessmentCheckURL { get; set; }
[StringLength(200)]
public string AssessmentCheckName { get; set; }
public virtual CVE CVE { get; set; }
}
如果我使用同一个数据库来创建一个 EDMX 文件(EF 设计器,而不是“代码优先”),那么模型图和 AssessmentCheck 类的外观如下(这与我的预期相符);
public partial class AssessmentCheck
{
public int AssessmentCheckID { get; set; }
public string CveID { get; set; }
public string AssessmentCheckSystem { get; set; }
public string AssessmentCheckURL { get; set; }
public string AssessmentCheckName { get; set; }
public virtual CVE CVE { get; set; }
}
什么给了?如何让实体框架在代码优先模型中创建关联,使“CveIDFK”不是“必需”?
明确地说,我的最终目标是从数据库创建类,创建“CVE”对象,将“AssessmentCheck”添加到“CVE”对象,然后添加“SaveChanges”。问题是当我这样做并尝试保存更改时,EF 说我需要明确提供“AssessmentCheck”对象的“CveIDFK”字段。鉴于 CVE 和 AssessmentChecks 之间的关系,我认为应该自动暗示这个 FK。我错过了什么吗?
编辑:
我更新了数据库以返回使用 CveID" 作为 AssessmentChecks 表中的外键名称,并重新创建了我的类。
这是我用来保存数据的代码;
CVE cve = new CVE
{
CveID = "CVE-2016-2140"
};
AssessmentCheck AC1 = new AssessmentCheck
{
AssessmentCheckName = "First Assessment check"
};
AssessmentCheck AC2 = new AssessmentCheck
{
AssessmentCheckName = "Second Assessment Check"
};
cve.AssessmentChecks.Add(AC1);
cve.AssessmentChecks.Add(AC2);
using (var context = new NVDModel())
{
try
{
context.Database.Log = Console.WriteLine;
context.CVEs.Add(cve);
context.SaveChanges();
}
}
我得到的错误是
处于“已添加”状态的“AssessmentCheck”类型实体具有以下内容 验证错误: - 属性:“CveID”,错误:“CveID 字段是必需的。”处于“已添加”状态的“AssessmentCheck”类型实体具有以下验证 e 错误: - 属性:“CveID”,错误:“CveID 字段是必需的。”
如果我从“AssessmentChecks”类的“CveID”字段中删除“必需”数据注释,它可以工作(外键自动插入而我没有明确提供),但我认为我不必删除它数据注释。
另外,如果我在将父级添加到上下文之后移动子级的添加,那也可以;
try
{
context.Database.Log = Console.WriteLine;
context.CVEs.Add(cve);
cve.AssessmentChecks.Add(AC1);
cve.AssessmentChecks.Add(AC2);
context.SaveChanges();
}
这是怎么回事?
【问题讨论】:
-
完全跑题了,但我把这个标题读作“拙劣的暗杀”。
-
在您的数据库截图中,
CvelDFK被标记为NOT NULL(因此是必需的)。在这种情况下,EF 做了正确的事情 -
@Rob 它绝对是必需的,但是在代码中,当我创建一个 CVE 对象并向它添加一个 AssessmentCheck 时,然后“SaveChanges”我认为 EntityFramework 应该自动填充“CveIDFK”外键字段,但它没有。相反,它告诉我 CveIDFK 字段是必需的,因此“保存”失败。我相信我不应该明确设置“CveIDFK”,它应该自动从关联中派生
-
我没有看到您首先在代码中进行关联的位置。如果将 CveIDFK 更改为 CveId(请注意这是数据库首先生成的内容),则可以按照惯例进行操作。如果在 CVE 对象上方添加 ForeignKey("CveIDFK"),则可以通过注释来完成。或者您可以使用 fluent api 来完成。 msdn.microsoft.com/en-us/data/jj819164.aspx显示保存时实际抛出错误的代码。
-
@SteveGreene 我很困惑,当我首先从数据库编写代码时,EF 不应该为我建立关联吗?它不应该承认这种关系吗?
标签: c# sql-server entity-framework ef-code-first edmx