Использование Linq To SQL для обновления записи из MVC3 ViewModel - PullRequest
1 голос
/ 02 августа 2011

Я пытаюсь обновить запись в базе данных значениями в ViewModel через Linq To SQL. У меня это работало, но с тех пор оно прекратилось (подробнее об этом позже).

У меня есть объект домена Customers, сопоставленный с таблицей. Мне не нужны все поля, поэтому я использую AutoMapper для сопоставления его с ViewModel (CustomerEditVM), который имеет подмножество полей Customer. Я делаю это в моем слое обслуживания:

public CustomerEditVM GetCustomerEditVMById(int custId)
{
    var domainCustomer = _repository.GetCustomerById(custId);

    Mapper.CreateMap<Customer, CustomerEditVM>();
    CustomerEditVM customer = Mapper.Map<Customer, CustomerEditVM>(domainCustomer);
    return customer;
}

Я отправляю модель представления CustomerEditVM в мое представление, и пользователь редактирует запись. В моем слое обслуживания я сопоставляю его с объектом Customer и вызываю метод Update в моем хранилище:

public void SaveCustomer(CustomerEditVM customer)
{
    Mapper.CreateMap<CustomerEditVM, Customer>();
    Customer newCust = Mapper.Map<CustomerEditVM, Customer>(customer);
    _repository.Update(newCust);
}

Вот мой репозиторий и метод обновления:

namespace AuctionAdmin.Models.Repositories
{
    public interface ICustomerRepository
    {
        Customer GetCustomerById(int custId);
        void Update(Customer customer);
    }

    public class CustomerRepository : ICustomerRepository
    {
        private AuctionAdminDataContext _dataContext;

        public CustomerRepository()
        {
            _dataContext = new AuctionAdminDataContext();
        }

        public Customer GetCustomerById(int custId)
        {
            var customer = _dataContext.Customers.SingleOrDefault(c => c.CustomerID == custId);

            return customer;
        }

        public void Update(Customer customer)
        {
            _dataContext.Customers.Attach(customer);
            _dataContext.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, customer);
            _dataContext.SubmitChanges();
        }
    }
}

Обновление раньше работало нормально, но теперь завершается ошибкой:

Невозможно обновить указанный объект. Объект больше не существует в базе данных.

Я не уверен, почему это работало так хорошо раньше, а теперь нет, но ясно, что я не использую Linq для правильного обновления базы данных. Как мне это сделать?

Спасибо

1 Ответ

1 голос
/ 02 августа 2011

Итак, я понимаю, что Automapper не был разработан для такой работы. Он выравнивает объекты, как вы делаете, чтобы получить модель представления, но на самом деле ничего не делает иначе. Я полагаю, что это сделано специально, потому что Джимми и Крю используют больше шаблонов команд для обмена сообщениями, чтобы сохранить вещи обратно в базу данных.

Однако я знаю, что это не решит твою проблему. Итак, вот несколько вещей.

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

public void SaveCustomer(CustomerEditVM customer)
{
    //Get the customer from repo
    var domainCustomer = _repository.GetCustomerById(customer.Id);

    Mapper.CreateMap<CustomerEditVM, Customer>();
    Customer newCust = Mapper.Map<CustomerEditVM, Customer>(domainCustomer);

    _repository.Update(newCust);
}

Однако, скорее всего, это не сработает из-за того, как работают linq2sql и automapper. Даже если отображение работает, linq2sql может не показать, что в объект были внесены изменения. Вам будет лучше составить карту вручную.

Кроме того, в Linq2Sql нет такой вещи, как Update.

public void Update(Customer customer)
    {
        _dataContext.Customers.Attach(customer);
        _dataContext.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, customer);
        _dataContext.SubmitChanges();
    }

Все, что вам нужно сделать, это получить объект из linq2sql, обновить его и вызвать SubmitChanges (); на _dataContext. Это позаботится об этом для вас. Я видел, что некоторые интерфейсы репозитория включают метод Update, но он ничего не делает в реализации Linq2Sql. Кроме того, вероятно, не самая лучшая идея вызывать SubmitChanges в методе обновления, так как вы можете захотеть обновить элементы, а затем отправить все изменения сразу, что является своего рода целью submitchanges (то есть единицы работы)

...