سؤال

I am using entity framework to get a IEnumerable<CustomersEntity>, and I need to cast this to a IEnumerable<CustomerBO> to display it in some view. I know how to do cast a IEnumerable<T1> to a IEnumerable<T2>; but in this case, who will be in charge of it ? I thought CustomerBO could do it, but is it correct for an object return a list of itself ? or have I to write a layer with only one function ? I am in a MVC project, so maybe the controller could be involved; but if possible I prefer to decouple it from the DAL...

Here is what I currently have:

Entity :

public class CustomerEntity
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Street { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public IEnumerable<Invoices> Invoices { get; set; }
}

And Business object:

public class CustomerBO
{
    public string FullName { get; set; }
    public string FullAddress { get; set; }
    public string InvoicesNumber { get; set; }
    public string InvoicesTotalAmount { get; set; }

    public CustomerBO(CustomerEntity customer)
    {
        //Instanciate the object
    }
}

Note I need a one-way only process; I won't have to insert a CustomerBO in the database.

هل كانت مفيدة؟

المحلول

Your CustomerBO class should have NO reference to the EF entity. This conversion should take place in side a repository. If the business object has any reference to the entity, it is still coupled to the database, and it can be difficult to run simulations, "what-if-scenarios" ect, independent of your data if you need to.

public class CustomerRepository
{
     // dont forget to close your connections, which I left out...
     public CustomerBO GetCustomer(id)
     {
          return Map(DBContext.Customers.Where(c => c.Id == id).Single());
     }

     public IEnumerable<CustomerBO> GetAllCustomers()
     {
          return Map(DBContext.Customers.Select(c => Map(c));
     }

     private CustomerBO Map(CustomerEntity entity)
     {
          CustomerBo bo = new CustomerBO();
          bo.FirstName = entity.FirstName;
          //etc
          bo.InvoicesNumber = entity.invoices.Count();
          bo.InvoicesTotalAmount = entity.invoices.select(i => i.Amount).Sum();
     }


}

You may think, this seems slow, but do not be tempted by the siren of premature optimization. Also, if you are very concerned about speed, you should use Dapper.net instead of entity framework.

You then call the repository from your controller, and map the BO to the view model in the controller, or just use the BO directly if it suits your purposes.

There is still coupling inside the repository, but it is limited to only there, so if you need to change your DB, you only have to change it one place

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى softwareengineering.stackexchange
scroll top