Как обновить одно поле определенных записей с помощью Entity Framework?
Я хочу обновить семью человека, которого его зовут pejman.
Это мой объект Класс:
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set;}
public DateTime BirthDate { get; set; }
public bool IsMale { get; set; }
public byte[] Image { get; set; }
public byte[] RowVersion { get; set; }
public virtual Person Parent { get; set; }
public virtual ICollection<PhoneNumber> PhoneNumber { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
public virtual PersonInfo PersonInfo { get; set; }
}
и мой метод обновления: (в Program.cs)
public static void Update(string name, string family)
{
var _person = new Person() { FirstName = name, LastName = family };
using (var newContext = new MyDbContext())
{
newContext.Persons.Attach(_person);
newContext.Entry(_person).Property(X => X.LastName).IsModified = true;
newContext.SaveChanges();
}
}
но это не сработает! в чем проблема?
EDIT: предположим, что я не знаю идентификатора человека, и я просто знаю имя человека, есть ли способ обновить семейство людей?
Ответы
Ответ 1
При создании экземпляра объекта Person отсутствует поле Id. Из-за этого Entity Framework не может найти существующее лицо.
Ваш код должен выглядеть так:
public static void Update(int id, string name, string family)
{
var _person = new Person() { Id = id , FirstName = name, LastName = family };
using (var newContext = new MyDbContext())
{
newContext.Persons.Attach(_person);
newContext.Entry(_person).Property(X => X.LastName).IsModified = true;
newContext.SaveChanges();
}
Ответ 2
EDIT: предположим, что я не знаю идентификатора человека, и я просто знаю имя человека, есть ли способ обновить семейство людей?
Я предполагаю, что поле FirstName
класса Person
содержит имя человека, а обновление семейства человек означает обновление поля LastName
.
Первый шаг состоит в том, чтобы получить все записи Person
с FirstName
равным имени человека, скажем, это "pejman", поэтому код будет таким, как показано ниже.
var personsToUpdate = newContext.Persons.Where(o => o.FirstName == "pejman");
Следующий шаг перечисляет personsToUpdate
и устанавливает для свойства LastName
имя семейства, которое вы хотите, затем вызовите метод .SaveChanges()
DbContext
, чтобы отправить изменения в базу данных. Скажем, вы хотите обновить фамилию человека до "MyFamilyName", код будет ниже
foreach (Person p in personsToUpdate)
{
p.LastName = "MyFamilyName";
}
newContext.SaveChanges();
Ниже приведен модифицированный код вашего метода Update
с параметрами name
и family
.
public static void Update(string name, string family)
{
using (var newContext = new MyDbContext())
{
// get all Persons with FirstName equals name
var personsToUpdate = newContext.Persons.Where(o => o.FirstName == name);
// update LastName for all Persons in personsToUpdate
foreach (Person p in personsToUpdate)
{
p.LastName = family;
}
newContext.SaveChanges();
}
}
Ответ 3
Для решения этой ошибки я получил значения по идентификатору из базы данных, хранящейся в Var Temprc.
Затем обновите поле Password, которое я хочу обновить.
Затем добавьте temprc в мою модель Userregistrations.
Затем помечается PasswordConfirm isModified.
затем Savechanges();
using (var db = new Entities())
{
var temprc = _reg.GetUserByID(Convert.ToInt32(Session["LogedUserID"]));
temprc.PasswordConfirm = U.NewPassword;
db.Userregistrations.Attach(temprc);
db.Entry(temprc).Property(x => x.PasswordConfirm).IsModified = true;
db.SaveChanges();
}
Ответ 4
Предполагая, что у вас есть экземпляр Person, который может найти db (как упоминал Paweł Bejger):
public class Person
{
/// <summary>
/// USAGE: await UpdateDbEntryAsync(myPerson, d => d.FirstName, d => d.LastName);
/// </summary>
async Task<bool> UpdateDbEntryAsync<T>(T entity, params Expression<Func<T, object>>[] properties) where T : class
{
try
{
var db = new RtTradeData.Models.ApplicationDbContext();
var entry = db.Entry(entity);
db.Set<T>().Attach(entity);
foreach (var property in properties)
entry.Property(property).IsModified = true;
await db.SaveChangesAsync();
return true;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("UpdateDbEntryAsync exception: " + ex.Message);
return false;
}
}
/// <summary>
/// The idea is that SomeFunction already has the instance of myPerson, that it wants to update.
/// </summary>
public void SomeFunction()
{
myPerson.FirstName = "Another Name"; myPerson.LastName = "NewLastName";
UpdateDbEntryAsync(myPerson, d => d.FirstName, d => d.LastName);
}
/// <summary>
/// Or directly requesting the person instance to update its own First and Last name...
/// </summary>
public void Update(string firstName, string lastName)
{
FirstName = "Another Name"; LastName = "NewLastName";
UpdateDbEntryAsync(this, d => d.FirstName, d => d.LastName);
}
Person myPerson = new Person { PersonId = 5, FirstName = "Name", LastName = "Family" };
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
см. также обновить одно поле в Entity Framework
и Единое обновление платформы Entity Framework
Ответ 5
Следующие работали для меня:
public ActionResult ChangePassword(Account account)
{
try
{
if (ModelState.IsValid)
{
db.Accounts.Attach(account);
db.Entry(account).Property(x => x.Password).IsModified=true;
db.Configuration.ValidateOnSaveEnabled = false;
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
{
Exception raise = dbEx;
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
string message = string.Format("{0}:{1}",
validationErrors.Entry.Entity.ToString(),
validationError.ErrorMessage);
raise = new InvalidOperationException(message, raise);
}
}
ModelState.AddModelError("", raise);
}
return View(account);
}