6
votes

I'm having a issue with Entity Framework and Code First. I have an entity with a Timestamp property, and I add an new record to the database, call SaveChanges, and it's all ok. When I try to delete the record I've just added, I get the following message:

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

It seems to me that EF has no knowledge that this new record exists in database, despite the fact that it is there. Sometimes, even when I try to update an different record I get the same message, but if I try to delete an different one it works.

Does anyone knows why this is happening?

Thanks in advance, Diego

EDIT I've assembled some code to make it easier to understand my problem:

I have two simple entities:

public class Entidade1
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    public string Descricao { get; set; }

    [Timestamp]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public byte[] RecTS { get; set; }
}

public class Entidade2
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    public string Descricao { get; set; }

    [Timestamp]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public byte[] RecTS { get; set; }

    public virtual Entidade1 Entidade1 { get; set; }
}

The Context:

public class DB : DbContext
{
    public DB() : base("DB")
    {
        this.Configuration.AutoDetectChangesEnabled = true;
        this.Configuration.LazyLoadingEnabled = true;
        this.Configuration.ProxyCreationEnabled = true;
    }

    public DbSet<Entidade1> Entidade1 { get; set; }
    public DbSet<Entidade2> Entidade2 { get; set; }
}

And the code:

var item = new Entidade1();

        item.Descricao = "teste";

        var db = new DB();

        db.Set(typeof(Entidade1)).Add(item);

        db.SaveChanges();

        var item2 = new Entidade2();

        item2.Descricao = "teste 2";
        item2.Entidade1 = item;

        db.Set(typeof (Entidade2)).Add(item2);

        db.SaveChanges();

        var q = (from c in db.Entidade1
                 where c.Descricao == "teste"
                 select c).FirstOrDefault();

        db.Set(typeof(Entidade1)).Remove(q);

        db.SaveChanges();

        var q2 = (from c in db.Entidade2
                  where c.Descricao == "teste 2"
                  select c).FirstOrDefault();

        db.Set(typeof (Entidade2)).Remove(q2);

        db.SaveChanges(); // Here I got the error
2
When the exceptions occurs and I call concurrencyException.Entries.Single().Reload(); it works, but I don't want an Exception to be thrown every time I save or delete a record. - Diego Modolo Ribeiro
Are you using threads at all? (eg, ASP.Net) - SLaks
No, it's a single thread application. I don't know if it's important, but my Context is static. - Diego Modolo Ribeiro
Try setting ProxyCreationEnabled to false. That helped me, but it's a workaround not a solution. - Patrick

2 Answers

4
votes

I've found out that the problem is a known bug in Entity Framework 4.0, and that it's presente since 2010 and will be resolved in the next version (hope in 4.5). When I update an object that has related objects, EF tries to update all the relations, and as nothing has changed in the parentes, it will give me the '0 rows' message.

Hope it helps someone.

1
votes

I suggest, using local scope for Context:

Using(var x = new MyObjectContext){
      //
      //....
      x.SaveChanges(); 
     }