Шаблон для обновления базы данных через свойство при использовании внутреннего отображения - PullRequest
0 голосов
/ 23 июля 2010

Я обнаружил небольшую проблему в своем приложении, и я не уверен, как лучше ее решить.

Я использую Linq to Sql, и у меня есть объект домена, который оборачивает объект Linq, чтобы я не предоставлял напрямую объекты Linq моему внешнему интерфейсу.

Итак, у меня есть что-то вроде:

class MyOrder : IOrder 
{
    Order _order; // this is the Linq entity

    public MyOrder(Order o) { ... }

    // Mapping between my domain Item class and the Linq class
    public void SetItemDetails(IItem item)
    {
        _order.Item = new Item
        { 
            StockCode = item.StockCode,
            Price = item.Price
        };                
    }

    // ...and the other way
    public IItem GetItemDetails()
    {
        return new MyItem
        {
            StockCode = _order.Item.StockCode,
            Price = _order.Item.Price
        }
    }
}

Это сработало нормально, поскольку все мои доменные объекты являются неизменяемыми, поэтому у меня фактически есть только действия Get и Set, а не Update действия.

Но теперь я достиг точки, где мне нужно обновляемое свойство.

Я хочу сделать что-то вроде следующего в моем интерфейсе MVC:

[AcceptVerbs(HttpVerbs.Post)]
public void SetCustomerDetails(int id, FormCollection form) 
{
    IOrder = _repository.GetOrderById(id);

    ICustomer customer = IOrder.GetCustomerDetails(); 

    // customer will already have some, but not all, fields set

    UpdateModel(customer);

    // now customer has all fields set

    _repository.SubmitChanges();

    // ... and we haven't actually updated anything!
}

Проблема должна быть очевидной - из-за сопоставления в классе MyOrder обновление MyOrder.Customer фактически не меняет никаких свойств базовых объектов Linq, поэтому обновление базы данных с помощью этого шаблона невозможно.

Я надеюсь, что кто-то может предложить решение этой проблемы, которое все еще сохраняет API относительно интуитивно понятным.

Например, я мог бы, вероятно, сделать что-то вроде следующего (на самом деле не проверено, но я думаю, что это должно работать):

ICustomer customer = IOrder.GetCustomerDetails(); 
UpdateModel(customer);
IOrder.SetCustomerDetails(customer)

... но для меня это безнадежно не интуитивное и действительно не подходящее решение.

Обратите внимание, что я не могу сделать ICustomer неизменным, так как тогда я не могу использовать метод MVC UpdateModel. Я думаю, что именно отсюда вытекает вся проблема.

1 Ответ

0 голосов
/ 23 июля 2010

вы также не должны подвергать свой доменный объект своим представлениям, вам нужен другой посредник (ViewModel, так как MS любит, чтобы вы их вызывали).

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

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

Затем вы можете UpdateModel, затем вызвать соответствующие методы домена, что-то вроде:

class UpdateCustomerDetailsViewModel
{
    string OrderId;
    string DeliveryAddress;
}

public void SetCustomerDetails(int id, FormCollection form) 
{
    var viewModel = new UpdateCustomerDetailsViewModel();
    UpdateModel(viewModel );

    IOrder = _repository.GetOrderById(id);

    ICustomer customer = IOrder.GetCustomerDetails(); 

    customer.UpdateDetails(viewModel.DeliveryAddress);

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