我首先是EF代码的新手,所以请对我宽容。
我有这些实体类:
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>();
}
}
使用映射配置:
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");
})
;
}
}
和一个相当通用的存储库类:
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();
}
}
使用上面的代码,我可以顺利地将新任务行插入到db中。 但是,当我尝试使用这个简单的代码更新任务时出现问题:
Task task = repository.Find(2);
if (task != null)
{
task.Name = "Test Update";
repository.Update(task);
repository.Save();
}
错误说:
违反PRIMARY KEY约束'PK_dbo.TaskAssignees'。不能 在对象'dbo.TaskAssignees'中插入重复键。声明有 已被终止。
请问有人给我启发吗?
答案 0 :(得分:0)
我认为您的问题可能在于您如何调用更新。
我不确定,但我认为您的实体已经由上下文管理,因此您不需要添加它以将其置于更新状态。如果您只是删除要更新的调用并尝试保存,那么一切都有效吗?