I am still new in EF code first, so please be lenient with me.
I have these entity classes:
public class User
{
public int UserId { get; set; }
public string UserName { get; set; }
public string EmailAddress { get; set; }
public string Password { get; set; }
public virtual ICollection<Task> Tasks { get; set; }
public virtual ICollection<Task> TaskAssignees { get; set; }
public User()
{
Tasks = new List<Task>();
}
}
public class Task
{
public int TaskId { get; set; }
public string Name { get; set; }
public virtual User CreateBy { get; set; }
public int UserId { get; set; }
public virtual ICollection<User> Assignees { get; set; }
public Task()
{
Assignees = new List<User>();
}
}
with mapping configuration:
public class UserMap : EntityTypeConfiguration<User>
{
public UserMap()
{
Property(u=>u.UserName)
.IsRequired()
.HasMaxLength(30);
Property(u => u.EmailAddress)
.IsRequired()
.HasMaxLength(255);
Property(u => u.Password)
.IsRequired()
.HasMaxLength(255);
}
}
public class TaskMap : EntityTypeConfiguration<Domain.Entities.Task>
{
public TaskMap()
{
Property(t => t.Name)
.IsRequired()
.HasMaxLength(255);
HasRequired(t => t.CreateBy)
.WithMany(u => u.Tasks)
.HasForeignKey(t => t.UserId)
.WillCascadeOnDelete(false)
;
HasMany(t => t.Assignees)
.WithMany(u => u.TaskAssignees)
.Map(a =>
{
a.ToTable("TaskAssignees");
a.MapLeftKey("TaskId");
a.MapRightKey("UserId");
})
;
}
}
and a fairly generic repository class:
public class EntityRepository<TEntity> : IEntityRepositoryGetWithCRUD<TEntity> where TEntity : class
{
internal DbContext context;
internal DbSet<TEntity> dbSet;
public EntityRepository(DbContext Context)
{
this.context = Context;
this.dbSet = context.Set<TEntity>();
}
public virtual IQueryable<TEntity> All
{
get { return dbSet; }
}
public virtual IQueryable<TEntity> AllIncluding(params System.Linq.Expressions.Expression<Func<TEntity, object>>[] IncludeProperties)
{
IQueryable<TEntity> query = dbSet;
foreach (var includeProperty in IncludeProperties)
{
query = query.Include(includeProperty);
}
return query;
}
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> Filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> OrderBy = null,
params System.Linq.Expressions.Expression<Func<TEntity, object>>[] IncludeProperties)
{
IQueryable<TEntity> query = dbSet;
if (Filter != null)
{
query = query.Where(Filter);
}
foreach (var includeProperty in IncludeProperties)
{
query = query.Include(includeProperty);
}
if (OrderBy != null)
{
return OrderBy(query).ToList();
}
else
{
return query.ToList();
}
}
public virtual TEntity Find(int Id)
{
return dbSet.Find(Id);
}
public virtual void Insert(TEntity Entity)
{
dbSet.Add(Entity);
}
public virtual void Update(TEntity Entity)
{
dbSet.Add(Entity);
context.Entry(Entity).State = EntityState.Modified;
}
public virtual void Delete(int Id)
{
var entity = dbSet.Find(Id);
dbSet.Remove(entity);
}
public virtual void Delete(TEntity Entity)
{
if (context.Entry(Entity).State == EntityState.Detached)
{
dbSet.Attach(Entity);
}
dbSet.Remove(Entity);
}
public virtual void Dispose()
{
context.Dispose();
}
public virtual void Save()
{
context.SaveChanges();
}
}
With the above codes, i can insert a new task row into db smoothly. However the problem arise when i tried to update the task with this simple code:
Task task = repository.Find(2);
if (task != null)
{
task.Name = "Test Update";
repository.Update(task);
repository.Save();
}
The error said:
Violation of PRIMARY KEY constraint 'PK_dbo.TaskAssignees'. Cannot insert duplicate key in object 'dbo.TaskAssignees'. The statement has been terminated.
Could anybody give me some enlightenment please?