实体框架代码首次更新记录不保存父母
问题描述:
我的代码在下面保存记录的罚款,但它不保存客户端。我没有得到任何错误,它将记录保存到数据库中,但不会与父客户端建立关系。在调试时,我已经逐步确定了var客户端实际上包含客户端对象。实体框架代码首次更新记录不保存父母
任何帮助非常感谢!
反正这里是我的代码:
using (var context = new TDBContext())
{
if (SelectedProject != null)
{
var client = (from x in context.Clients
where x.ID == (Guid) comboClient.SelectedValue
select x).FirstOrDefault();
Project project = new Project()
{
ID = (Guid) SelectedProject,
ProjectCode = textProjectCode.Text,
Client = client,
ProjectStart = dateProjectStart.SelectedDate,
Active = checkActive.IsChecked
};
context.Projects.Attach(project);
context.Entry(project).State = EntityState.Modified;
context.SaveChanges();
}
else
{
MessageBox.Show("Project ID not loaded!", "Error!", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
项目单位:
public Project()
{
}
[Key]
public Guid ID { get; set; }
public string ProjectCode { get; set; }
public Client Client { get; set; }
public DateTime? ProjectStart { get; set; }
public bool? Active { get; set; }
客户端实体:
public Client()
{
}
[Key]
public Guid ID { get; set; }
public string ClientName { get; set; }
public byte[] ClientLogo { get; set; }
public ICollection<Project> Projects { get; set; }
答
编辑(终于得到了它的工作):
我创建了一个单独的方法来更新客户端。我从我的主要保存方法中调用它。这每次都有效。我敢肯定,我可以做得更好(即都在同一个方法):
private void SaveClient()
{
using (var context = new PDBContext())
{
var client = (from x in context.Clients
where x.ID == (Guid) comboClient.SelectedValue
select x).FirstOrDefault();
var project = (from x in context.Projects
where x.ID == SelectedProject
select x).FirstOrDefault();
project.Client = client;
context.Projects.Attach(project);
context.Entry(project).State = EntityState.Modified;
context.SaveChanges();
}
PopulateClientCombo();
}
答
你必须在客户端Id列只是不分配客户参考。 EF足够聪明,可以检查ClientId何时存在并且具有与客户端导航属性不同的id,但是如果id为空,它将完全忽略该Client导航属性。
编辑
啊,然后调用context.Projects.Add(项目),而不是将其更改为修改。
答
我不是很确定你使用EF的,但我会尽力给这个问题一个镜头。请注意,这与您的方法完全不同。简而言之,我将创建/获取客户端标识并将其添加到正在添加的新项目对象中。
多了一个属性添加到您的项目实体:
public Guid ClientId { get; set; }
。这与public Client Client { get; set; }
并列。当您应用迁移时,您的项目表现在具有ClientId以引用客户端(一对多关系,是不是?)应用迁移并确保表本身具有引用。
-
在您的方法中,在创建新项目时添加ClientId。这应该够了。
Project project = new Project() { ID = (Guid) SelectedProject, ProjectCode = textProjectCode.Text, ClientId = (Guid)comboClient.SelectedValue, // Your client's Guid. Make sure this record exists in the database. ProjectStart = dateProjectStart.SelectedDate, Active = checkActive.IsChecked };
这是我和我的项目做。当你查询,你加载数据和EntityFramework有方法为你做。另请参见:Loading Related Data
的做这件事的一个时髦的一种方式(我会获取客户端和更新其子集),但它可能会工作,如果你还设置Project.Client的实体状态修改为好。另外,当我指望父记录的存在时,我更喜欢'First()'到'FirstOrDefault()'。我至少会确定它不是null。 –