2

I'd using 3 tier architecture on my web project. DAL -> EF 4 wrapper with classic CRUD method (AddEntity, RemoveEntity adn so on) BAL -> business logic and query exposing (selectByName, byCity, bySomeOtherProperty). UI - Aspx page

My problem is about navigationProperty exposed by EF. If I have a CustomerRepostiory, aspx side I don't want allow operation on entity that are not Customer, supposing follwing POCO class:

public class Customer
{
    public int Id {get; set;}
public string Name {get; set;}
public ICollection<Orders> Order{get;set;}
}

and on aspx you execute something like this:

var customer = bll.getCustomerByName("alex");
customer.Order.Add(new ..) // BAD, I don't want allow it

What should I do? Maybe I must create a poco class wrapper in order to "hide" some properties? Which really is best approach?

bit
  • 934
  • 1
  • 11
  • 32
  • Why don't you want to allow this? Is it because you want to restrict what can be done at the UI layer? Why is it BAD in your case? – Davin Tryon Jun 02 '12 at 18:34
  • Yes, I want to restrct what can be done at the UI layer. Also, my BLL contains Insert, Delete, Update and Save methods thus they are the only one responsable for CRUD operations. Every command needs for some validation, if you use a navigationProperty to add something I cannot execute any controls. You have to pass for Insert method. – bit Jun 02 '12 at 19:05

2 Answers2

2

Expose your collection as an IEnumerable instead, that way the collection will be read only

You would have to do something like:

class Customer
{
   private List<Order> orders();
   Customer()
   {
      this.orders = new List<Order>();
   }

   public IEnumerable<Order> Orders { get { return this.orders.AsEnumerable(); } }

   // you will need a public method to mutate the collection

   public void AddOrder(Order order)
   {
      // implement custom logic, fire domain events, etc
      this.orders.Add(order);
   }
}

EDIT:

If you cannot modify your entity (which seems odd to me...) you could try to use the ObservableCollection<>

Something odd like this

class MyCustomer : Customer
{
   private ObservableCollection<Order> orders;
   internal bool AllowMutateCollection;
   public MyCustomer()
   {
      this.Orders = this.orders = new ObservableCollection<string>();
      this.orders.CollectionChanged += (_, __) =>
      {
          if(!this.AllowMutateCollection)
          {
             throw new NotImplementedException();
          }
      };
   }
}

Now you would have to set the AllowMutateCollection when you will allow to mutate your entity, which becomes a real pain and probably this will be cause of some bugs... I do not recommend it

However I would strongly recommend you to redefine a little bit your design, wrapping your class and expose an IEnumerable instead, that would be cleaner and easier to maintain

Check this question

Fire an event when Collection Changed (add or remove)

Community
  • 1
  • 1
Jupaol
  • 21,107
  • 8
  • 68
  • 100
1

Write a subclass for Customer, override Orders, make the getter do whatever access right checking you want

Filip
  • 2,285
  • 1
  • 19
  • 24