1

I am currently refactoring a WPF application that is built on the principles of the Repository Pattern. It uses Entity Framework as its ORM, and is Database First. Each of those entities is wrapped by Repository, the interfaces of which are then used in Unit Of Work. Those units of work are then used by ViewModels.

However, a single transaction like, say, CreateInvoice() affects several tables. For example, CreateInvoice() would insert a Sale record in Sales Table, deduct available stock in Stock Table, and so on and so forth. Here is a sample code for that:

public void Commit(IContainInvoiceInfo InvoiceInfo)
{
    _invoiceInfo = InvoiceInfo;

    try
    {
        _uow.BeginTransaction();
        InsertInSalesTable();
        UpdateCurrentStock();
        UpdatePacketStock();
        InsertStockHistoryEntries();
        InsertInTaxTable();
        _uow.Complete();
        _uow.EndTransaction();
    }
    catch (Exception ex)
    {
        _uow.RollBack();
        throw ex;
    }
}

private void InsertInSalesTable()
{
    _uow.salesrepo.Add(new Sale
    {
        ID = _invoiceInfo.InvoiceNum.ToString(),
        client = _invoiceInfo.SelectedClient.ID,
        saledate = _invoiceInfo.InvoiceDate,
        totalvalue = _invoiceInfo.GrandTotal,
        purchaseorder = string.IsNullOrWhiteSpace(_invoiceInfo.PONumber) ? null : _invoiceInfo.PONumber + "dated: " + _invoiceInfo.PODate.ToString("dd-MM-yy")
    });
}
...

So, basically, ViewModels are doing the heavy-lifting of properly inserting data into the proper tables in a database.

The problem is that since I am using Entity Framework DB First approach, the model generated is an anaemic one. They are simple data classes with absolutely no behaviour.

I could encapsulate this logic in the Unit Of Work itself, or even create stored procedure in the database itself, or create a separate service layer which would consume the Units of Work and then make the ViewModels use the services instead of the Units of Work.

Which is the correct place to encapsulate this insertion/update logic?

  • Are you not using databinding at all? The "heavy lifting" looks like, from the code sample, as something that is mostly automated by bindings. – wondra Jun 22 '18 at 11:07
  • I am using databinding. In fact, I am using Caliburn.Micro for that purpose – Mycroft Holmes Jun 22 '18 at 11:43
  • I should have been a bit clear, perhaps. Let's say, there's a view where users can create an invoice. So, based on that invoice information, records need to be saved/updated into the Sales Table and Stock Table of the database. Now, the ViewModel uses the SalesUnitOfWork to update the respective tables. However, this means that ViewModel is quite aware of the Database Schema. Is there any way to make the ViewModel absolutely Database-agnostic? – Mycroft Holmes Jun 22 '18 at 11:49
  • You can always move your business logic from the app to the database or separate .dll if that would make you more comfortable... That would, however, render ORM and/or MVVM mostly inapplicable. Which is place better would depend on your situation. I was just pointinting out that InsertInSalesTable should probably never existed in the first place if you used bidnings, because you would have a Sale object bound and filled from UI optionally inserted in an EF-backed collection through a ICommand ~your Commit. – wondra Jun 22 '18 at 12:04
  • So you're probably talking about facade pattern. I am not using that, unfortunately. The view has textboxes and comboboxes that are simply bound to string and ObservableCollection (BindableCollection because I'm using Caliburn). Creating a Sales object from those input data is done inside the ICommand. – Mycroft Holmes Jun 22 '18 at 12:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.