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は無意味であることはわかっています。最初にエラーが発生した後に削除するリビジョンがあることを確認するために追加しました。私の開発マシンでは誰もDBにアクセスしていないため、競合状態もありません。
Better to materialize the query then check if it has items and delete those you need to delete all in memory.=>しかし、それはまさに私が避けたいことです(そしてEF.Extenedが適していること)。何かが変更されたかどうかは実際には気にしません-DBのようDELETE from Revisions WHERE Item_Id = @Id;にクエリを実行するだけだと思います。

更新:
問題を再現するために小さなデモ プロジェクトを作成しました: HERE
継承に関連しているようです。で同じことを試してみると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);

EntitySets プロパティでは、基本クラスのエンティティ セットにすぎないため、2 番目の Single が問題のようです。この問題には簡単な解決策があります。クエリでは常に (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 に答える