我一直在修补一下在实体框架(从现有的MSSQL数据库)生成的模型中包含外键的选项。
我们假设我有一个人和公司的模型,我想同时创建两者。公司可以有多个人。人有Id,Name,CompanyId,公司有Id和Name。
我不太确定我应该如何创建彼此相关的新对象。我有点想到的一种方法是:
// Company needs ID and Name, and ID is auto generated, so -1
Model.Company newCompany = Model.Company.CreateCompany(-1, "Test Inc");
// Person needs ID, Name and a CompanyID. What is CompanyId supposed to be?
Model.Person newPerson = Model.Person.CreatePerson(-1, "John Doe", -1);
// And to actually get the Company relation going
newPerson.Company = newCompany;
然后将其添加到上下文并保存。
现在,这有效,但我不确定这是我应该做的吗?
因为,如果我们想象我会抽象出这些的创作(这是我在我的应用程序的大部分内容中所拥有的)。也许我们有以下功能,我仍然需要提供ID,即使此对象的EntityState未知。它可能有我所知道的ID,并非所有公司都是新公司。所以我不能这样做:
public static Model.Person CreatePerson(string name, Model.Company company) {
Model.Person newPerson = Model.Person.CreatePerson(-1, name, company.Id);
return newPerson;
}
但是,如果公司是新添加的对象,则会失败。因此,我是否相信在Create-method中使用实际ID是无用的?因为除非我检查实体状态,否则我最终将不得不执行以下操作:
public static Model.Person CreatePerson(string name, Model.Company company) {
Model.Person newPerson = Model.Person.CreatePerson(-1, name, -1);
newPerson.Company = company;
return newPerson;
}
我意识到在您拥有ID而不是对象的情况下使用外键ID创建对象的好处,并且您实际上不需要从数据库中获取整个对象。但是我对如何最好地解决这个问题感到很困惑。
答案 0 :(得分:1)
您可能必须同时设置外键属性和导航属性,以涵盖方法中新Company
和现有属性的两种情况:
public static Model.Person CreatePerson(string name, Model.Company company) {
Model.Person newPerson = Model.Person.CreatePerson(-1, name, company.Id);
newPerson.Company = company;
return newPerson;
}
company
是新的,EF将忽略newPerson.CompanyId
值,并仅根据导航属性newPerson.Company
创建关系。company
已存在(状态为Unchanged
或Modified
),则FK属性newPerson.CompanyId
必须与主键值newPerson.Company.Id
匹配,否则您将得到例外。