我有实体Exhibit
和Exhibition
,它们是多对多的关系。 Exhibit
也可以有多个类别。
public class ExhibitionModel
{
public ExhibitionModel()
{
this.Exhibits = new List<ExhibitModel>();
}
[Key]
public int ExhibitionId { get; set; }
//some props
public virtual IList<ExhibitModel> Exhibits { get; set; }
}
public class ExhibitModel
{
[Key]
public int ExhibitId { get; set; }
//some props
public virtual IList<CategoryModel> Categories { get; set; }
public virtual IList<ExhibitionModel> Exhibitions { get; set; }
}
public class CategoryModel
{
[Key]
public int CategoryId { get; set; }
public virtual IList<ExhibitModel> Exhibits { get; set; }
}
当我创建一个新的展览时,在我的ViewModel中,我有所有的展览参数和字符串,其中包含选定的展品ID。
public ActionResult Create(CreateExhibitionViewModel model)
{
try
{
if (ModelState.IsValid)
{
if (!String.IsNullOrEmpty(model.ExhibitsString))
{
model.Exhibition.AddExhibitsToModel(model.ExhibitsString, exhibitsRepo);
}
var result = exhibitionsRepo.Create(model.Exhibition);
if (result != null)
{
return RedirectToAction("Index");
}
}
return View(model);
}
catch
{
return View();
}
}
public static void AddExhibitsToModel(this ExhibitionModel model, string exhibitsString, ExhibitsRepository exhibitsRepo)
{
if (!String.IsNullOrEmpty(exhibitsString))
{
string[] ids = exhibitsString.Split(',');
foreach (string stringId in ids)
{
int id;
ExhibitModel exhibit = new ExhibitModel();
if (int.TryParse(stringId, out id))
{
exhibit = exhibitsRepo.Read(id);
}
model.Exhibits.Add(exhibit);
}
}
}
来自Create
ExhibitionRepository
方法
public ExhibitionModel Create(ExhibitionModel exhibition)
{
try
{
using (var dbContext = new MuseumContext())
{
foreach (var exhibit in exhibition.Exhibits)
{
if (exhibit.ExhibitId != 0 && dbContext.Entry(exhibit).State == EntityState.Detached)
{
dbContext.Exhibits.Attach(exhibit);
}
}
var result = dbContext.Exhibitions.Add(exhibition);
dbContext.SaveChanges();
return result;
}
}
catch (Exception ex)
{
return null;
}
}
正如您所看到的,我正在附加每个展览实体以避免创建新记录。当两个展品具有相同的类别时,附加第二个展览会抛出异常
附加“Project.Models.CategoryModel”类型的实体失败,因为同一类型的另一个实体已具有相同的主键值。如果图中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新的并且尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图表,然后根据需要将非新实体的状态设置为“未更改”或“已修改”。
我该怎么做才能解决这个问题?
此致 康拉德
答案 0 :(得分:0)
当EF已经跟踪实体时,通常会发生此错误。我想它可能在这里:
exhibit = exhibitsRepo.Read(id);
您有两种选择。
您可以使用AsNoTracking()设置Read方法。
也许db.Exhibits.AsNoTracking().Where(x => x.Id== id);
这样您就明确告诉EF不要跟踪实体。
如果展品已经在数据库中,只需将它们添加到展览馆藏并保存更改,EF就会为您制作并保存参考(在展品记录中)。 无需重新附加实体。