Entity Framework с ASP.NET MVC - PullRequest
3 голосов
/ 22 мая 2009

Как я могу использовать строго типизированные контроллеры с EntityObjects?

Мои неудачи ...

Сначала я попробовал это:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, Department Model)
{
    db.SaveChanges();
    return RedirectToAction("Index");
}

Не удалось сохранить изменения в базе данных. Итак, я попытался прикрепить модель к моему ObjectContext:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, Department Model)
{
    db.Attach(Model);
    db.SaveChanges();
    return RedirectToAction("Index");
}

Это не удалось, потому что «объект с нулевым значением EntityKey не может быть присоединен к контексту объекта». Итак, я попытался присвоить EntityKey:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, Department Model)
{
    Model.EntityKey = (from Department d in db.Department
                       where d.Id == id
                       select d).FirstOrDefault().EntityKey;
    db.Attach(Model);
    db.SaveChanges();
    return RedirectToAction("Index");
}

Это не удалось, поскольку "объект с таким же ключом уже существует в ObjectStateManager. ObjectStateManager не может отслеживать несколько объектов с одним и тем же ключом."

Как это должно работать?

Ответы [ 4 ]

3 голосов
/ 22 мая 2009

Дело в том, что в качестве входных данных у вас есть не полный объект модели с измененными свойствами - это просто «начало» нового объекта со всеми свойствами, которые вы хотите перезаписать на уже существующей сущности. Вы не публикуете ни одного из свойств ID,

Это выглядит немного многословно, но это лучшее, что я нашел, поэтому я делаю это в своих проектах (в соответствии с именами ваших классов, с тем, что пропущено, сделано ...):

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, Department Model)
{
    var dbDepartment = (from Department d in db.Department
                        where d.Id == id
                        select d).FirstOrDefault() as Department

    dbDepartment.Name = Model.Name;
    dbDepartment.Color = Model.Color;
    // etc, assigning values manually...

    try
    {
        db.SaveChanges();
    }
    catch (Exception ex)
    {
        // oops...
    }
    return RedirectToAction("Index");
}
1 голос
/ 15 февраля 2012

Как насчет этого

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, Department dept)
{
    Department tmp = new Department()
    {
        Id = dept.Id
    };
    try
    {
        db.Departments.Attach(dept, tmp);
        db.Save();
    }
}

Может быть, часть tmp можно обменять на вызов UpdateModel после части Attach, но я не уверен.

Редактировать: только что посмотрел документацию на Attach (Entity e, Entity original), и он действительно заменит оригинал на e (или обновит оригинал соответственно или w / e).

1 голос
/ 22 мая 2009

Попробуйте db.AttachTo () вместо db.Attach ()

Как описано здесь

"Вызовите AttachTo для ObjectContext, чтобы прикрепить объект к определенному объекту, заданному в контексте объекта. Также сделайте это, если объект имеет нулевое значение (Nothing в Visual Basic) EntityKey."

Редактировать: на самом деле, вам может потребоваться вызвать ApplyPropertyChanges () в этом случае.

Редактировать 2: Вы можете создать ключ сущности для своего объекта с помощью кода, подобного следующему:

public EntityKey GetEntityKey(string entitySetName, object keyValue)
{
  IEnumerable<KeyValuePair<string, object>> entityKeyValues =
    new[]
    {
      new KeyValuePair<string, object>("Id", keyValue)
    };

  var key = new EntityKey(string.Concat("YOUR_OBJECT_CONTEXT_NAME.", entitySetName), entityKeyValues);
  return key;
}

И затем вы бы назвали это как-то так для ключей сущностей, основанных на одном столбце базы данных под названием «Id»:

var entityKey = GetEntityKey ("Клиент", 23);

Я использую аналогичный метод в своем собственном коде EF, за исключением аргумента типа Generic, чтобы избежать необходимости использовать строку для имени класса сущности.

0 голосов
/ 14 декабря 2011

Я не рекомендую использовать POCO в вашем приложении MVC. Вы должны использовать DTO или модель.

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

[AcceptVerbs(HttpVerbs.Post)]<br> public ActionResult Edit(Guid id, Department Model) {<br> var entity=from m in db.Models where m.Id == Model.id select m;<br> Model entityAttached=entity.FirstOrDefault();<br> //replace all the new values in you object<br> db.SaveChanges();<br> }

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...