具有卸载导航属性的EF删除实体

时间:2011-10-21 17:27:11

标签: entity-framework domain-driven-design entity-framework-4.1 navigation-properties

我有一个实体。 Mandate。每个任务都有一个必需的:与Person(NavigationProperty)的许多关系。我使用DbContext API(LazyLoadingEnabled,AutoDetectChangesEnabled,ValidateOnSaveEnabled,ProxyCreationEnabled)

现在我想删除一个Mandate实体。任务实体由AsNoTracking()的另一个上下文加载。

message.Result.
    ObserveOn(On<DataComposition>.Scheduler).
    Where(r => r).
    Subscribe(_ =>
    {
        using (var unit = UnitOfWork.Begin())
        {
            var mandate = this.SelectedItem.OriginalEntity;

            this.mandateRepository.Attach(mandate);
            // mandate.Person.ToString();

            this.mandateRepository.Delete(mandate);

            unit.Commit();
        }

        this.List.RemoveOnUi(this.SelectedItem);
    });

现在在提交期间,我收到以下异常:Entities in 'CodeFirstContainer.Mandates' participate in the 'Mandate_Person' relationship. 0 related 'Mandate_Person_Target' were found. 1 'Mandate_Person_Target' is expected.

如果我在填充/选择期间包含Person属性,或者如果我访问Property(延迟加载),但是我不喜欢仅为删除情况实现/保留许多实体,则删除有效我不喜欢向db发出多个DELETE查询!

1 个答案:

答案 0 :(得分:2)

如果您填充了导航属性mandate.Person,则会出现以下SQL语句......

delete [dbo].[Mandates]
where (([Id] = @0) and ([PersonId] = @1))

...被发送到数据库,让我认为导航属性确实必须填充一个具有正确PersonId的人来删除父。

我不知道为什么Entity Framework不会发送带有主键的删除语句......

delete [dbo].[Mandates]
where ([Id] = @0)

......正如我所料。

修改

如果Mandate实体具有PersonId导航属性的外键属性Person,则将预期的SQL(上面的第二个)发送到数据库。在这种情况下,Person导航属性可以是null,而FK属性PersonId的值无关紧要。

修改2

如果您不想引入FK属性,那么具有最少DB-roundtrip-cost的方式可能是获取该人的Id,然后在内存中创建一个具有该密钥的虚拟人:

// ...
var personId = context.Mandates
    .Where(m => m.Id == mandate.Id)
    .Select(m => m.Person.Id)
    .Single();

mandate.Person = new Person { Id = personId };

this.mandateRepository.Attach(mandate);
this.mandateRepository.Delete(mandate);
// ...