Здравствуйте, я новичок в программировании MVC и столкнулся с довольно странной ошибкой, которую я не могу обернуть. Я создаю приложение MVC 5, и когда я пытаюсь использовать опцию редактирования на моем контроллере, родительская сущность и дочерние сущности, кажется, все загружаются правильно, однако, когда я пытаюсь сохранить изменения обратно, я получаю ошибку «Присоединение сущности» типа 'X.Models.ApplicationUser' не удалось, потому что другой объект того же типа уже имеет то же значение первичного ключа ". У меня есть ниже ViewModel / Models:
public class EditMatchesViewModel
{
public int ID { get; set; }
[Required]
public DateTime Date { get; set; }
[Required]
public string Division { get; set; }
[Required]
public Team HomeTeam { get; set; }
[Required]
public Team AwayTeam { get; set; }
public List<Game> Games { get; set; }
public MatchStatus Status { get; set; }
}
public class Game
{
public int ID { get; set; }
public GameType GameType { get; set; }
public virtual ApplicationUser AwayPlayer1 { get; set; }
public virtual ApplicationUser AwayPlayer2 { get; set; }
public virtual ApplicationUser HomePlayer1 { get; set; }
public virtual ApplicationUser HomePlayer2 { get; set; }
public int AwayScore1 { get; set; }
public int AwayScore2 { get; set; }
public int HomeScore1 { get; set; }
public int HomeScore2 { get; set; }
}
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
public string UserRole { get; set; }
public bool Active { get; set; }
public Team Team { get; set; }
}
public class Team
{
public int ID { get; set; }
public string TeamName { get; set; }
public bool Active { get; set; }
public virtual ICollection<ApplicationUser> Players { get; set; }
}
И следующий контроллер:
public async Task<ActionResult> Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Match matchData = await db.Matches.
Where(m => m.ID == id).
Include(t => t.AwayTeam).
Include(t2 => t2.HomeTeam).
Include(x => x.Games.Select(g => g.GameType)).
FirstOrDefaultAsync();
EditMatchesViewModel model = new EditMatchesViewModel
{
Date = matchData.Date,
Division = matchData.Division,
AwayTeam = matchData.AwayTeam,
HomeTeam = matchData.HomeTeam,
ID = matchData.ID,
Status = matchData.Status,
Games = matchData.Games.ToList()
};
ViewBag.teams = new SelectList(db.Teams.Where(a => a.Active == true).ToList(), "ID", "TeamName");
ViewBag.players = db.Users.AsNoTracking().Where(a => a.Active == true).ToList();
ViewBag.gametypelist = db.GameType.Where(a => a.Active == true).AsNoTracking().ToList();
if (model == null)
{
return HttpNotFound();
}
return View(model);
}
// POST: Matches/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "ID,Date,Division,HomeTeam,AwayTeam,Games")] Match match)
{
if (ModelState.IsValid)
{
db.Entry(match).State = EntityState.Modified;
//db.Set<Match>().AddOrUpdate(match);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(match);
}
И, наконец, следующий вид:
@model TennisClub.Models.EditMatchesViewModel
@{
ViewBag.Title = "Update match and game information.";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Match</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.ID)
<div class="form-group">
@Html.LabelFor(model => model.Date, htmlAttributes: new { @class =
"control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Date, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Date, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Division, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Division, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Division, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.HomeTeam, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.HomeTeam.ID, (IEnumerable<SelectListItem>)ViewBag.Teams, "Please Select Home Team", new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.HomeTeam, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.AwayTeam, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.AwayTeam.ID, (IEnumerable<SelectListItem>)ViewBag.Teams, "Please Select Away Team", new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.AwayTeam, "", new { @class = "text-danger" })
</div>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>Game Type</th>
<th>Away Team</th>
<th>Home Team</th>
<th>Away Score</th>
<th>Home Score</th>
</tr>
</thead>
<tbody>
@for (var i = 0; i < Model.Games.Count; i++)
{
<tr>
@Html.HiddenFor(model => Model.Games[i].ID)
<td>@Html.LabelFor(model =>
Model.Games[i].GameType.Name, htmlAttributes: new { @class = "control-label
col-md-2" })<br />@Html.DropDownListFor(model => Model.Games[i].GameType.ID,
new SelectList(ViewBag.gametypelist, "ID", "Name",
Model.Games[i].GameType.ID), null, new { @class = "form-control" })</td>
<td>
@Html.LabelFor(model =>
Model.Games[i].AwayPlayer1.UserName, htmlAttributes: new { @class =
"control-label col-md-2" })<br />@Html.DropDownListFor(model =>
Model.Games[i].AwayPlayer1.Id,
Model.Games[i].AwayPlayer1 != null ? new SelectList(ViewBag.players, "Id",
"UserName", Model.Games[i].AwayPlayer1.Id) :
new SelectList(ViewBag.players, "Id", "UserName"), "Please select away
player 1", new { @class = "form-control" })
<br />
@Html.LabelFor(model =>
Model.Games[i].AwayPlayer2.UserName, htmlAttributes: new { @class =
"control-label col-md-2" })<br />@Html.DropDownListFor(model =>
Model.Games[i].AwayPlayer2.Id,
Model.Games[i].AwayPlayer2 != null ? new SelectList(ViewBag.players, "Id",
"UserName", Model.Games[i].AwayPlayer2.Id) :
new SelectList(ViewBag.players, "Id", "UserName"), "Please select away
player 2", new { @class = "form-control" })
</td>
<td>
@Html.LabelFor(model =>
Model.Games[i].HomePlayer1.UserName, htmlAttributes: new { @class =
"control-label col-md-2" })<br />@Html.DropDownListFor(model =>
Model.Games[i].HomePlayer1.Id,
Model.Games[i].HomePlayer1 != null ? new SelectList(ViewBag.players, "Id",
"UserName", Model.Games[i].HomePlayer1.Id) :
new SelectList(ViewBag.players, "Id", "UserName"), "Please select home
player 1", new { @class = "form-control" })
<br />
@Html.LabelFor(model =>
Model.Games[i].HomePlayer2.UserName, htmlAttributes: new { @class =
"control-label col-md-2" })<br />@Html.DropDownListFor(model =>
Model.Games[i].HomePlayer2.Id,
Model.Games[i].HomePlayer2 != null ? new SelectList(ViewBag.players, "Id",
"UserName", Model.Games[i].HomePlayer2.Id) :
new SelectList(ViewBag.players, "Id", "UserName"), "Please select home
player 2", new { @class = "form-control" })
</td>
<td>
@Html.LabelFor(model => Model.Games[i].AwayScore1,
htmlAttributes: new { @class = "control-label col-md-2" })<br
/>@Html.EditorFor(model => Model.Games[i].AwayScore1, new { htmlAttributes =
new { @class = "form-control" } })<br />
@Html.LabelFor(model => Model.Games[i].AwayScore2,
htmlAttributes: new { @class = "control-label col-md-2" })<br />@Html.EditorFor(model => Model.Games[i].AwayScore2, new { htmlAttributes = new { @class = "form-control" } })
</td>
<td>
@Html.LabelFor(model => Model.Games[i].HomeScore1, htmlAttributes: new { @class = "control-label col-md-2" })<br />@Html.EditorFor(model => Model.Games[i].HomeScore1, new { htmlAttributes = new { @class = "form-control" } })<br />
@Html.LabelFor(model => Model.Games[i].HomeScore2, htmlAttributes: new { @class = "control-label col-md-2" })<br />@Html.EditorFor(model => Model.Games[i].HomeScore2, new { htmlAttributes = new { @class = "form-control" } })
</td>
</tr>
}
</tbody>
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
Я пробовал некоторые вещи из других постов, но не повезло, кажется, что ApplicationUser всегда загружается независимо от того, говорю я, включать его или нет. Также кажется, что он всегда включает в себя идентификатор команды, который затем включает игроков снова и снова и снова. Любая помощь или направление будет принята с благодарностью.