2

I've created my generic repository based on this codeproject sample . Update() method isn't working (without any error). when I add this line of code:

this.context.Entry(entity).State = EntityState.Modified;

this error occured:

Attaching an entity of type 'MySolution.DAL.Event' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.

what should I do?

All of my codes are here:

context:

public abstract class BaseEntity
{
    public Int64 ID { get; set; }
    public DateTime AddedDate { get; set; }
    public DateTime ModifiedDate { get; set; }
    public string IP { get; set; }
}
public class MyContext:DbContext
{
    public MyContext()
        : base("MyConnectionString")
    {
        base.Configuration.LazyLoadingEnabled = false;
        base.Configuration.ProxyCreationEnabled = false;
        base.Configuration.ValidateOnSaveEnabled = false;
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

        var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
      .Where(type => !String.IsNullOrEmpty(type.Namespace))
      .Where(type => type.BaseType != null && type.BaseType.IsGenericType
           && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
        foreach (var type in typesToRegister)
        {
            dynamic configurationInstance = Activator.CreateInstance(type);
            modelBuilder.Configurations.Add(configurationInstance);
        }
        base.OnModelCreating(modelBuilder);

    }

    public new IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity
   {
       return base.Set<TEntity>();
   }

    //public DbSet<Event> Events { get; set; }

}

Repository:

public class Repository<T> where T : BaseEntity
{
    private readonly MyContext context;
    private IDbSet<T> entities;
    string errorMessage = string.Empty;


    public Repository(MyContext context)
    {
        this.context = context;
    }

    public T GetById(object id)
    {
        return this.Entities.Find(id);
    }

    public T Insert(T entity)
    {
        try
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            var savedEntity=  this.Entities.Add(entity);
            this.context.SaveChanges();
            return savedEntity;
        }
        catch (DbEntityValidationException dbEx)
        {

            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {
                    errorMessage += string.Format("Property: {0} Error: {1}",
                    validationError.PropertyName, validationError.ErrorMessage) + Environment.NewLine;
                }
            }
            throw new Exception(errorMessage, dbEx);
        }
    }

    public void Update(T entity)
    {
        try
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }


            //this.context.Entry(entity).State = EntityState.Modified;not worked
            //this.context.Entry(entity).CurrentValues.SetValues(entity);not worked
            this.context.SaveChanges();
        }
        catch (DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {
                    errorMessage += Environment.NewLine + string.Format("Property: {0} Error: {1}",
                    validationError.PropertyName, validationError.ErrorMessage);
                }
            }

            throw new Exception(errorMessage, dbEx);
        }
    }

    public void Delete(T entity)
    {
        try
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }

            this.Entities.Remove(entity);
            this.context.SaveChanges();
        }
        catch (DbEntityValidationException dbEx)
        {

            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {
                    errorMessage += Environment.NewLine + string.Format("Property: {0} Error: {1}",
                    validationError.PropertyName, validationError.ErrorMessage);
                }
            }
            throw new Exception(errorMessage, dbEx);
        }
    }

    public virtual IQueryable<T> Table
    {
        get
        {
            return this.Entities;
        }
    }

    private IDbSet<T> Entities
    {
        get
        {
            if (entities == null)
            {
                entities = context.Set<T>();
            }
            return entities;
        }
    }
}
alite
  • 105
  • 1
  • 1
  • 9
  • Why are you adding that line of code? – JohnnyHK Sep 02 '15 at 16:27
  • because update method not work and the record in database doesn't change. – alite Sep 02 '15 at 16:37
  • Are you working with detached entities? The error message itself gives instructions on what to do to fix the error, but without more detail it isn't really possible to definitively answer the question. – Nathan Sep 02 '15 at 18:00
  • I've added more detail. – alite Sep 02 '15 at 18:10
  • You might have a look at my answer on [ASP.NET MVC - Attaching an entity of type 'MODELNAME' failed because another entity of the same type already has the same primary key value](http://stackoverflow.com/questions/23201907/asp-net-mvc-attaching-an-entity-of-type-modelname-failed-because-another-ent/39557606#39557606). – Murat Yıldız Sep 18 '16 at 12:29

1 Answers1

0

You can use

this.context.Entry(entity).State = EntityState.Modified

then when you update an entity you can use

public void Edit(Post post)
{ 
   var postInDb=DBReadWrite<Post>().GetById(post.ID);
   postInDb.ModifiedProp=post.ModifiedProp;
   DBReadWrite<Post>().Update(postInDb);
}

if you dont want this you can use reflectionType yuo,,ou can catch keyattribute in repository and find entity in db and modified.

your code not works because EF is thinking you add an entity and it says I have same entity

cemil
  • 61
  • 7