У меня есть класс сущностей Пользователь:Entity Framework - Просмотр 2 отсоединен Entity обновление
public class User
{
[Key]
public int UserId { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string SecretQuestion { get; set; }
public string SecretAnswer { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public Nullable<byte> UserType { get; set; }
public Nullable<bool> Enabled { get; set; }
public Nullable<DateTime> Created { get; set; }
public Nullable<DateTime> Modified { get; set; }
public void LoadWCPModel(UserWCPModel model)
{
Username = model.Username;
Password = model.Password;
SecretQuestion = model.SecretQuestion;
SecretAnswer = model.SecretAnswer;
UserType = model.UserType;
Enabled = model.Enabled;
}
}
У меня есть класс модели для моего Web Portal Configuration (WCP):
public class UserWCPModel
{
[Key]
public int UserId { get; set; }
[Display(Name = "Username")]
[Required]
public string Username { get; set; }
[Display(Name = "Password")]
[Required]
public string Password { get; set; }
[Display(Name = "Secret question")]
[Required]
public string SecretQuestion { get; set; }
[Display(Name = "Secret answer")]
[Required]
public string SecretAnswer { get; set; }
[Display(Name = "User type")]
[Required]
public Nullable<byte> UserType { get; set; }
[Display(Name = "Enabled")]
[Required]
public Nullable<bool> Enabled { get; set; }
[ScaffoldColumn(false)]
public Nullable<DateTime> Created { get; set; }
[ScaffoldColumn(false)]
public Nullable<DateTime> Modified { get; set; }
/// Parameterless constructor for MVC model binder.
public UserWCPModel()
{
Created = DateTime.UtcNow;
}
}
Цель: Получить UserWCPModel и сохранять ТОЛЬКО данные из этой модели, не нанося вреда данным, заполненным другими приложениями (электронная почта, телефон, полное имя), а также полностью избегая перезагрузки данных из базы данных.
Во-первых, HttpPost Редактировать действие:
[HttpPost]
public ActionResult Edit(UserWCPModel model)
{
if (ModelState.IsValid)
{
WrappedE result;
repo.Update(model, out result);
if (result.ErrorCode != ErrorCodes.Success)
{
/// Add error handling;
}
return RedirectToAction("Index");
}
return View(model);
}
Как вы можете видеть, я только вызвать метод Update из репозитория, пропусканием UserWCPModel.
Теперь вот метод репозитория:
public void Update(UserWCPModel model, out WrappedE result)
{
User user = new User();
user.UserId = model.UserId;
db.Users.Attach(user);
user.LoadWCPModel(model);
user.Modified = DateTime.UtcNow;
SaveToDb(out result);
}
- Я построить пустой объект пользователя.
- Я присваиваю ему ID, взятый из модели.
- Я прикрепляю его к пользователям DbSet.
- Я загружаю данные из объекта UserWCPModel в объект User.
- Я установил измененное время (не важно).
- Я вызываю db.SaveChanges() (это то, что делает SaveToDb).
Цель достигнута! Нет второго запроса SELECT. Нет данных экономии, не связанных с моделью. Отсутствие вызова IsModified для каждого свойства. Отсутствие вреда ранее введенным данным, выходящим за рамки модели.
я подправил его так сильно, что я должен поделиться этим здесь, и надеюсь на некоторые комментарии: D
Надежда кто-то найдет это полезное :)
Это работает, но только потому, что вы делаете DB и UI намеренно «непоследовательными», так сказать, поскольку у вас есть * необязательные/нулевые столбцы в базе данных, но * обязательные * свойства в пользовательском интерфейсе. Возможно, вам это нужно или нужно, но я бы назвал это очень «специальной» архитектурой. – Slauma