Tôi có mối quan hệ nhiều-nhiều giữa Issues
và Scopes
trong ngữ cảnh EF của tôi. Trong ASP.NET MVC, tôi đưa ra một hình thức chỉnh sửa cho phép người dùng chỉnh sửa một vấn đề cụ thể. Ở dưới cùng của biểu mẫu, là danh sách các hộp kiểm cho phép họ chọn phạm vi áp dụng cho vấn đề này. Khi chỉnh sửa một vấn đề, nó có khả năng sẽ luôn luôn có một số phạm vi liên kết với nó đã - những hộp này sẽ được kiểm tra rồi. Tuy nhiên, người dùng có cơ hội kiểm tra nhiều phạm vi hơn hoặc xóa một số phạm vi được kiểm tra hiện tại. Mã của tôi nhìn một cái gì đó như thế này để tiết kiệm chỉ Issue:Thực thể cập nhật đối tượng khung cùng với các thực thể con (thêm/cập nhật nếu cần)
using (var edmx = new MayflyEntities())
{
Issue issue = new Issue { IssueID = id, TSColumn = formIssue.TSColumn };
edmx.Issues.Attach(issue);
UpdateModel(issue);
if (ModelState.IsValid)
{
//if (edmx.SaveChanges() != 1) throw new Exception("Unknown error. Please try again.");
edmx.SaveChanges();
TempData["message"] = string.Format("Issue #{0} successfully modified.", id);
}
}
Vì vậy, khi tôi cố gắng thêm trong logic để lưu các phạm vi liên quan, tôi đã cố gắng một vài điều, nhưng cuối cùng, đây là những gì làm cho ý nghĩa nhất đối với tôi:
using (var edmx = new MayflyEntities())
{
Issue issue = new Issue { IssueID = id, TSColumn = formIssue.TSColumn };
edmx.Issues.Attach(issue);
UpdateModel(issue);
foreach (int scopeID in formIssue.ScopeIDs)
{
var thisScope = new Scope { ID = scopeID };
edmx.Scopes.Attach(thisScope);
thisScope.ProjectID = formIssue.ProjectID;
if (issue.Scopes.Contains(thisScope))
{
issue.Scopes.Attach(thisScope); //the scope already exists
}
else
{
issue.Scopes.Add(thisScope); // the scope needs to be added
}
}
if (ModelState.IsValid)
{
//if (edmx.SaveChanges() != 1) throw new Exception("Unknown error. Please try again.");
edmx.SaveChanges();
TempData["message"] = string.Format("Issue #{0} successfully modified.", id);
}
}
Nhưng, thật không may, mà chỉ ném ngoại lệ sau đây:
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
tôi đang làm gì sai?
Thật hoàn hảo! Và nhìn vào hồ sơ SQL, nó chỉ là một "thêm" cuộc gọi đến DB cho .Load(), nhưng cách sạch hơn thêm/loại bỏ hơn cách tôi sử dụng để làm điều đó bằng tay với thủ tục được lưu trữ. Cảm ơn! – Jorin
Câu trả lời hay của James. Đây là một vấn đề phổ biến trong nhiều ứng dụng (thêm/xóa thẻ hiệu quả). Không phải là thời gian cho một chức năng cấp hệ thống để làm điều này mà không có một màn hình đầy mã? Một cái gì đó như * issue.Scopes.ReplaceWith (myScopes); * – TFD
@TFD vâng tôi nghe thấy bạn. Nếu không, đội EF có rất nhiều trên đĩa của nó, một phương pháp mở rộng đơn giản sẽ làm các trick mặc dù phải không? –