I am using EF 6.1 with EF.Extended and I am trying to execute the following:
if (allRevisions != null && allRevisions.Any(r => r.Item.Id == itemId))
allRevisions.Where(r => r.Item.Id == itemId).Delete();
allRevisions
is a DbSet<Revision>
from my current DbContext
(this code is inside a generic helper method).
When I execute this I get the following exception:
Sequence contains no matching element.
Which is not true as there is a matching revision and the Any
is also true.
Furthermore if I execute the following it works fine:
if (allRevisions != null && allRevisions.Any(r => r.Item.Id == itemId))
{
foreach (var revision in allRevisions.Where(r => r.Item.Id == itemId))
allRevisions.Remove(revision);
}
But that is exactly the way you should be able to avoid with EF.Extended.
Am I doing something wrong or is this a bug in EF.Extended?
PS: I know that the Any
is pointless - I added that to make shure there are revisions to delete after I got the error the first time. There is also no race-condition as on my dev-machine no one else is hitting the DB.
Better to materialize the query then check if it has items and delete those you need to delete all in memory.
=> but thats exactly what I want to avoid (and what EF.Extened is good for). I actually don't care if something has changed - I would expect it to simply execute a query like DELETE from Revisions WHERE Item_Id = @Id;
in the DB.
UPDATE:
I created a small demo-project to reproduce the problem: HERE
It seems to be connected to inheritance. If I try the same thing with the ContentRevision
it works, but with MyRevision
, which inherits from it, it does not.
I faced the same problem. So I used your example to locate the issue. It seems to be in inheritance. In class MetadataMappingProvider is following code
// 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);
and the second Single seems to be the trouble, because in EntitySets property are just entity sets for base classes. There is a simple solution to this problem. Always use the base class (from EF point of view) in query. For example if we have following mapping:
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; }
}
this code will throw an error:
using (var context = new TestContext())
{
context.Items.OfType<ItemWithContent>()
.Where(o => string.IsNullOrWhiteSpace(o.Content)).Delete();
}
but this code will work correctly:
using (var context = new TestContext())
{
context.Items
.Where(o => o is ItemWithContent &&
string.IsNullOrWhiteSpace((o as ItemWithContent).Content)).Delete();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.