0

Прежде всего, пожалуйста, несите меня, поскольку я довольно новичок в структуре MVC/Entity. Я пытаюсь сделать частичное обновление первой базы данных кода сущности для конкретного авторизованного пользователя с помощью MVC5 ...Обновление только для зарегистрированных пользователей - объект сущности не может ссылаться на несколько экземпляров IEntityChangeTracker

Я создал дополнительный класс под названием UserProfile для расширения класса asp.net Identity ApplicationUser. Вот код:

public class UserProfile 
{ 
    [Key, ForeignKey("ApplicationUser")] 
    public string UserId { get; set; } 

    public virtual ApplicationUser ApplicationUser { get; set; } 

    public string Username { get; set; } 
} 

Я также расширил класс ApplicationUser включить класс UserProfile в качестве дополнительного свойства:

public class ApplicationUser : IdentityUser 
{ 
    public virtual UserProfile UserProfile { get; set; } 
} 

Я тогда расширенный класс AccountController (генерируется автоматически, используя при asp.net Идентичность), чтобы добавить дополнительный метод, называемый Welcome ...

[HttpPost] 
[ValidateAntiForgeryToken] 
[Authorize] 
public ActionResult Welcome([Bind(Include = "UserId,Username")] UserProfile userProfile) 
{ 
    var user = UserManager.FindById(User.Identity.GetUserId()); 

    if (ModelState.IsValid) 
    { 
     userProfile.ApplicationUser = user; 

     db.UserProfile.Attach(userProfile); 
     db.Entry(userProfile).Property(u => u.Username).IsModified = true; 
     db.SaveChanges(); 

     return RedirectToAction("Index", "Home"); 
    } 

    return View(userProfile); 
} 

Однако, когда я пытаюсь отправить форму и выполнить приветствия метод, я получаю ВОЛП мычание ошибка:

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

Я пробовал обычные поиски Google, чтобы понять, как/почему это происходит, но не понимаю, как я мог бы иметь несколько экземпляров любой IEntityChangeTracker это?

Для дальнейшего уточнения, что я пытаюсь сделать здесь, убедитесь, что только текущий зарегистрированный пользователь может обновить объект UserProfile (я не могу найти хороший шаблон для этого где-нибудь по какой-либо причине?).

Я также знаю, что, как FK UserId доступен на модели UserProfile, я просто не мог пропустить установив userProfile.ApplicationUser и написать условие так:

if (userProfile.UserId == user.Id) 

Однако, от того, что я m, чтобы понять, как читать статьи и учебные пособия по EF, это не обязательно в этом случае? Мне также немного непросто разоблачить свойство UserId на странице, даже как скрытое поле.

Так что я полагаю, есть два вопроса ...

  1. Почему я получаю сообщение об ошибке несколько экземпляров, и как я могу решить это?
  2. Каков правильный метод/шаблон для использования, чтобы пользователь, который в настоящий момент вошел в систему, смог обновить свой собственный UserProfile?

ответ

0

Ваша непосредственная ошибка связана с тем, что объект отслеживается двумя экземплярами вашего контекста. А именно, UserManager создается экземпляром вашего контекста приложения, а затем, скорее всего, вы определяете другой экземпляр где-то в вашем контроллере.

Вы выбираете пользователя из контекста UserManager, присваиваете ему экземпляр UserProfile, а затем пытаетесь сохранить экземпляр UserProfile в отдельный контекст. Это включает пользователя в сохранение, поэтому теперь его отслеживают в двух контекстах. Чтобы исправить это, вам просто нужно убедиться, что вы имеете дело только с одним экземпляром контекста. Обычно инъекция зависимостей - лучший способ справиться с этим.

Однако вы можете полностью решить проблему, просто не имея UserProfile.Весь смысл Identity - предоставить вам расширяемые классы аутентификации, которые вы можете использовать .. UserProfile был необходим с SimpleMembership, потому что базовый пользовательский объект, член пользовательской части ASP.NET, мог бы быть расширен не. Если вы просто добавите свои свойства профиля в свой класс ApplicationUser, как и должно быть, вам не нужно даже ничего работать.

+0

Спасибо, Крис. Я ценю то, что вы говорите, в связи с тем, что не нужно расширять класс ApplicationUser с помощью UserProfile, однако в некоторых случаях в этих случаях будет необходимо, чтобы эти наборы данных были отдельными. Скажем, например, что UserProfile не был расширением объекта User per-se (назовите его сообщениями, если хотите) - не будет ли та же проблема при попытке обновить только данные пользователя? –

+0

Ну, тогда именно инъекция зависимостей становится очень важной. Доверьтесь мне. Я отложил внедрение DI на некоторое время, когда я впервые начал работу, и это повредит вам в долгосрочной перспективе. Начните прямо сейчас. –

+0

Не могли бы вы привести пример кода, как DI мог бы работать в этом случае? На данный момент я просто полагаюсь на строительные леса Visual Studio, чтобы создавать контроллеры из моей модели. –

Смежные вопросы