C# 如何在EF中移动具有导航属性的子对象

C# 如何在EF中移动具有导航属性的子对象,c#,entity-framework,C#,Entity Framework,我有两个人可以有阿滕德记录。我想合并这两个,保留主Atendee(如果他有),否则使用辅助Atendee。然后删除第二个 在SQL中,我会这样写: UPDATE dbo.atendee SET personid = @main.id WHERE id = @person.atendeeid DELETE FROM people WHERE id = @person.id 我在EF中尝试了以下操作,但出现错误: if (person.AtendeeId != null) {

我有两个人可以有阿滕德记录。我想合并这两个,保留主Atendee(如果他有),否则使用辅助Atendee。然后删除第二个

在SQL中,我会这样写:

UPDATE dbo.atendee SET personid = @main.id WHERE id = @person.atendeeid
DELETE FROM people WHERE id = @person.id
我在EF中尝试了以下操作,但出现错误:

    if (person.AtendeeId != null)
    {
        if (main.AtendeeId == null)
        {
            main.AtendeeId = person.AtendeeId;
            main.Atendeed = person.Atendeed;
        }
        person.AtendeeId = null;
        person.Atendeed = null;
    }

    db.Persons.Remove(person);
错误是:

发生引用完整性约束冲突:主键 不能删除作为引用完整性约束一部分的属性 除非已设置从属对象,否则在从属对象未更改时更改 该协会的主要对象。主要对象必须是 已跟踪且未标记为删除

有人能解释一下移动孩子的最佳实践是什么吗

在C#POCO's。人有

public virtual int? AtendeeId { get; set; }
[ForeignKey("Id")]
public virtual Atendee Atendeed { get; set; }
而阿滕德:

public virtual int PersonId { get; set; }
public virtual Person Person { get; set; }
在SQL中,Atendes有一个

PersonId(int, not null)
人们有一个

Atendeeid(int, null)

使用导航属性来执行移动,而不是FKs。在这两种情况下,一定要给孩子们加载。因此,如果一个人被设置为有一个可选的与会者,其中该人持有AttendeeId,那么您将该与会者从一个人移动到另一个人的逻辑是:

targetPerson.Attendee = sourcePerson.Attendee;
sourcePerson.Attendee = null;
context.SaveChanges();
在加载了attendee的情况下检索目标和源:

var targetPerson = context.People.Include(x=>x.Attendee).SingleOrDefault(x=>x.PeopleId == targetId);
var sourcePerson = context.People.Include(x=>x.Attendee).SingleOrDefault(x=>x.PeopleId == sourceId);

进行相关检查,以确保在转移之前存在与会者。EF最好通过导航属性及其代理类和上下文跟踪中的表示来执行这些操作,而不是试图通过ID来执行此操作。

如果要删除第二个人,合并两个人有什么意义。你不能把第二个人带走吗?但请尝试将ATENDEID设置为主对象。我不会修改person.atendeeid或Atendeed属性,因为它将在删除person对象后自动完成。然后,我会释放要传输给第二个人的Atendee信息。设置ATENDEID是什么意思?原来我的问题是代码首先生成了一个坏的DB。出于某种原因,从atendee到person的FK是atendee的ID列,而不是atendee表的personId列。