Как обновить одно поле определенных записей с помощью 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);
}