2012-05-23 6 views
0

Я использую рамку сущности 4.3 в моем приложении MVC 3, при попытке обновить объект (создание и удаление работает отлично) Я получаю эту ошибку:Ошибка при попытке обновить объект

Store update, insert, or delete statement affected an unexpected number of rows (0)

Когда я попал в режим отладки, я увидел, что по методе [HttpPost] нет корма Id поставлялись:

public ActionResult Edit(Feed feed) 
    { 
     if (ModelState.IsValid) 
     { 
      db.Entry(feed).State = EntityState.Modified; 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     ViewBag.FolderId = new SelectList(db.Folders, "FolderId", "Name", feed.FolderId); 
     return View(feed); 
    } 

хотя в обычном Получе идентификатора в передаются. это мои объекты

корм:

public class Feed 
{ 
    [ScaffoldColumn(false)] 
    public int FeedId { get; set; } 

    [StringLength(150, ErrorMessage = "The {0} must be less then {1} charecters")] 
    public string Title { get; set; } 

    [ScaffoldColumn(false)] 
    public string Description { get; set; } 

    [Required(ErrorMessage = "you must enter a valid link")] 
    [StringLength(500, ErrorMessage = "The {0} must be less then {1} characters long.")] 
    public string LinkUrl { get; set; } 

    [ScaffoldColumn(false)] 
    public DateTime PublishDate { get; set; } 

    [ScaffoldColumn(false)] 
    public string Image { get; set; } 

    [ForeignKey("Folder")] 
    [Required(ErrorMessage="you must choose a folder")] 
    public int FolderId { get; set; } 

    public virtual Folder Folder { get; set; } 

    public Feed() 
    { 
     PublishDate = new DateTime(2012, 1, 1); 
    } 
} 

Папка:

public class Folder 
{  
    public int FolderId { get; set; } 

    [Required(ErrorMessage = "you must enter a folder name")] 
    [StringLength(150, ErrorMessage = "the {0} must be less then {1} charecters")] 
    public string Name { get; set; } 
} 

Я искал решение, но ни один из них не работал, как пытаются метод обновления, который не существует в DbContext или определение свойства [Key] над FeedId и FolderId.

+0

У вас есть FeedId' на ваш взгляд? Вы должны округлить его значение, например, в скрытом поле, чтобы вернуть его в HTTP Post. –

+0

Thank это была моя проблема. Я добавил @ Html.HiddenFor (model => model.FeedId) к моему представлению –

+0

@Moran - Вам не следует пытаться управлять самим собой ... Это может привести к проблемам, особенно при многопоточности (например, в MVC) или с использованием нескольких контекстов. – Basic

ответ

0

Нельзя вручную поддерживать состояние объекта - отслеживание изменений должно выполняться контекстом.

Вы используете модель представления и предполагаете, что она должна быть прикреплена к базе данных.

Вам нужно сделать что-то вроде ..,

Feed DbFeed = DBSet.Where(f => f.id = feed.Id); 
DbFeed.Property = NewValue; 
db.SaveChanges(); 

(извините, возможно, неправильный синтаксис - Я работаю в VB по умолчанию)

То есть, получить новый экземпляр объекта поток из DB Context, а затем выполнить изменения на заданном вами объекте.

Это потому, что контекст фактически не дает вам простой объект Feed, а скорее анонимный тип, который обертывает его и имеет те же свойства. Оболочка переопределяет ваши методы и обнаруживает изменения свойств, которые поддерживают состояние.

Объект корма вы получаете от вашей точки зрения не содержит эту оболочку, следовательно, проблемы

+0

Извините, что не согласен с этим. Вы делаете базу данных в оба конца, чтобы EF начал отслеживать объект «Feed» с этим конкретным идентификатором. Вы можете просто просто 'db.Feeds.Attach (feed);' then 'db.Entry (feed) .State = EntityState.Modified' –

0

Entity Framework отслеживает объекты, корм вы получите от вашего зрения неотслеживаемый. Шаблон для этой ситуации извлечь объект, который вы хотите обновить из БД, а затем вызвать UpdateModel, которые будут применяться изменения из неотслеживаемой субъекта к вашему гусеничного объекта, который затем можно сохранить ..

if (ModelState.IsValid) 
    { 
     var trackedEntity = db.Find(feed.Id) 
     UpdateModel(trackedEntity); 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 
0

по-видимому, но поместив в мою модель атрибут [ScaffoldColumn (false)], он не создал его в моем представлении и там, где идентификатор не был передан.

Я добавил @Html.HiddenFor(model => model.FeedId) к моей модели и это позаботилось о проблеме.

0

Видимо, у вас были проблемы с параллелизмом. Ваше состояние обновления должен быть запущен как:

UPDATE tableA SET colA = 'value' WHERE colX1 = 'compare1' AND colX2 = 'compare2'; 

Это colXn может быть ваши первичные ключи и т.д., или может быть каждый столбец вы используете.Если вы не обрабатываете параллелизм, если кто-то получает данные в то же время, что и вы, измените и сохраните их перед вами, ваш оператор WHERE никогда не будет соответствовать, поскольку информация о записи, которую вы обновляете, уже имеет новую информацию.

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