DBSet.Where(...)。删除() - > "没有匹配元素"这不是真的

时间:2014-05-06 17:30:08

标签: c# entity-framework entity-framework-6.1 entity-framework-extended

我正在使用带有EF.Extended的EF 6.1,我正在尝试执行以下操作:

if (allRevisions != null && allRevisions.Any(r => r.Item.Id == itemId))
    allRevisions.Where(r => r.Item.Id == itemId).Delete();

allRevisions是我当前DbSet<Revision>中的DbContext(此代码位于通用帮助方法中)。
当我执行此操作时,我得到以下异常:

  

序列不包含匹配元素。

这是不正确的,因为有匹配的修订,Any也是如此 此外,如果我执行以下操作,它可以正常工作:

if (allRevisions != null && allRevisions.Any(r => r.Item.Id == itemId))
{
    foreach (var revision in allRevisions.Where(r => r.Item.Id == itemId))
        allRevisions.Remove(revision);
}

但这正是您应该通过EF.Extended避免的方式。

我做错了什么或者这是EF.Extended中的错误?

P.S。:我知道Any毫无意义 - 我补充说,为了让shure在我第一次收到错误后有删除修订版。在我的开发机器上也没有竞争条件,没有其他人在击中DB Better to materialize the query then check if it has items and delete those you need to delete all in memory. =&gt;但这正是我想要避免的(以及EF.Extened的优点)。我实际上并不关心某些事情是否发生了变化 - 我希望它只是在数据库中执行DELETE from Revisions WHERE Item_Id = @Id;之类的查询。

更新
我创建了一个小型演示项目来重现问题:HERE
它似乎与继承有关。如果我使用ContentRevision尝试相同的操作,但是MyRevision继承了它,但它没有。

1 个答案:

答案 0 :(得分:4)

我遇到了同样的问题。所以我用你的例子来找到问题。它似乎是继承。在类MetadataMappingProvider中是以下代码

        // Get the entity set that uses this entity type
        var entitySet = metadata
            .GetItems<EntityContainer>(DataSpace.CSpace)
            .Single()
            .EntitySets
            .Single(s => s.ElementType.Name == entityType.Name);

并且第二个Single似乎是麻烦,因为在EntitySets属性中只是基类的实体集。这个问题有一个简单的解决方案。始终在查询中使用基类(从EF的角度来看)。 例如,如果我们有以下映射:

    public class Item
{
    public long Id { get; set; }
}

public class ItemWithContent : Item
{
    public string Content { get; set; } 
}

public class TestContext : DbContext
{
    public IDbSet<Item> Items { get; set; }
}

此代码将引发错误:

    using (var context = new TestContext())
{
    context.Items.OfType<ItemWithContent>()
        .Where(o => string.IsNullOrWhiteSpace(o.Content)).Delete();
}

但是这段代码可以正常工作:

using (var context = new TestContext())
{
    context.Items
        .Where(o => o is ItemWithContent && 
            string.IsNullOrWhiteSpace((o as ItemWithContent).Content)).Delete();
}