我已根据此codeproject sample创建了我的通用存储库。 Update()
方法无效(没有任何错误)。当我添加这行代码时:
this.context.Entry(entity).State = EntityState.Modified;
发生此错误:
附加“MySolution.DAL.Event”类型的实体失败,因为同一类型的另一个实体已具有相同的主键值。如果图中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新的并且尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图表,然后根据需要将非新实体的状态设置为“未更改”或“已修改”。
我该怎么办?
我的所有代码都在这里:
上下文:
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; }
}
存储库:
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;
}
}
}
答案 0 :(得分:0)
您可以使用
this.context.Entry(entity).State = EntityState.Modified
然后 更新实体时,可以使用
public void Edit(Post post)
{
var postInDb=DBReadWrite<Post>().GetById(post.ID);
postInDb.ModifiedProp=post.ModifiedProp;
DBReadWrite<Post>().Update(postInDb);
}
如果您不希望这样做,则可以使用ReflectionType来,您可以在存储库中捕获keyattribute并在db中找到实体并进行修改。
您的代码不起作用,因为EF认为您添加了一个实体,并且说我有相同的实体