我有一个包含图像实体集合的食谱实体。在我的控制器中,我尝试保存一个附有两个新图像的新配方:
_recipeService.Insert(recipe);
try
{
foreach (Image img in recipe.Images)
{
_imageService.Update(img);
}
_recipeService.Save();
在后台,我使用工作单元模式来确保所有服务都使用相同的 DbContext,并且在任何服务上调用 Save() 都会保存所有实体。因此,如果我在创建过程中将两个图像附加到我的食谱中,我会在尝试保存时收到以下错误:
AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.
我确定这与两个图像实体的 ID 均为 0 的事实有关。这里的最佳做法是什么?
FWIW,这是我的初始迁移:
public override void Up()
{
CreateTable(
"dbo.Recipe",
c => new
{
ID = c.Int(nullable: false, identity: true),
CategoryId = c.Int(nullable: false),
Title = c.String(),
Summary = c.String(),
Directions = c.String(),
CookingTime = c.Int(nullable: false),
CreationDate = c.DateTime(nullable: false),
PostedDate = c.DateTime(),
LastModifiedDate = c.DateTime(nullable: false),
Visible = c.Boolean(nullable: false),
TagList = c.String(),
Ingredient_ID = c.Int(),
})
.PrimaryKey(t => t.ID)
.ForeignKey("dbo.Category", t => t.CategoryId, cascadeDelete: true)
.ForeignKey("dbo.Ingredient", t => t.Ingredient_ID)
.Index(t => t.CategoryId)
.Index(t => t.Ingredient_ID);
CreateTable(
"dbo.Image",
c => new
{
ID = c.Int(nullable: false, identity: true),
RecipeId = c.Int(nullable: false),
ImageUrl = c.String(nullable: false),
MainImage = c.Boolean(nullable: false),
})
.PrimaryKey(t => t.ID)
.ForeignKey("dbo.Recipe", t => t.RecipeId, cascadeDelete: true)
.Index(t => t.RecipeId);
谢谢,
克里斯
编辑:为配方服务添加代码
使用 Barbecurian.Data;使用 Barbecurian.Models;使用系统;使用 System.Collections.Generic;使用 System.Linq;使用 System.Web;
public class RecipeService : Service<Recipe>
{
private IService<Tag> _tagService;
public RecipeService(IUnitOfWork unitOfWork, IService<Tag> tagService)
{
_unitOfWork = unitOfWork;
_tagService = tagService;
_repo = _unitOfWork.RecipeRepository;
}
public override void Insert(Recipe recipeToCreate)
{
List<Tag> tags = new List<Tag>();
foreach (Tag tag in recipeToCreate.Tags)
{
if (_tagService.Get(filter: t => t.Name == tag.Name).Count() > 0)
{
tags.Add(_tagService.Get(filter: t => t.Name == tag.Name).SingleOrDefault());
}
else
{
Tag newTag = new Tag() {
Name = tag.Name
};
_tagService.Insert(newTag);
tags.Add(newTag);
}
}
recipeToCreate.Tags = tags;
// Validation logic
if(Validate(recipeToCreate))
_repo.Insert(recipeToCreate);
}
protected override bool Validate(Recipe recipeToValidate)
{
//Ensure recipe has a unique title
if (_repo.Get(r => r.Title == recipeToValidate.Title).Count() > 0)
_validationState.AddError("Title", "That title already exists.");
return _validationState.IsValid;
}
}
}
这继承自:
public abstract class Service<TEntity> : IService<TEntity> where TEntity : class, IModel
{
protected IRepository<TEntity> _repo;
protected IValidationDictionary _validationState;
protected IUnitOfWork _unitOfWork;
public virtual IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = ""){
return _repo.Get(filter, orderBy, includeProperties);
}
public virtual TEntity GetByID(int id, string includeProperties = ""){
return _repo.GetByID(id, includeProperties);
}
public virtual void Insert(TEntity entity){
_repo.Insert(entity);
}
public virtual void Delete(object id){
_repo.Delete(id);
}
public virtual void Delete(TEntity entity){
_repo.Delete(entity);
}
public virtual void Update(TEntity entity)
{
_repo.Update(entity);
}
public virtual void Save()
{
_unitOfWork.Save();
}
public virtual void Dispose()
{
_unitOfWork.Dispose();
}
protected abstract bool Validate(TEntity entity);
public IValidationDictionary ValidationState
{
get
{
return _validationState;
}
set
{
_validationState = value;
}
}
}
}