首先我还是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();
}
错误说:
违反主键约束“PK_dbo.TaskAssignees”。无法在对象“dbo.TaskAssignees”中插入重复键。该语句已终止。
有人可以给我一些启示吗?