我正在使用带有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
继承了它,但它没有。
答案 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();
}