3

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

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

allRevisionsDbSet<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 中的错误?

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

更新:
我创建了一个小型演示项目来重现问题:这里
似乎与继承有关。如果我尝试用ContentRevision它做同样的事情,但MyRevision它继承自它,它不会。

4

1 回答 1

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();
}
于 2015-02-16T15:16:26.933 回答