Old forum URL: forums.lhotka.net/forums/t/8597.aspx

FrazerS posted on Monday, March 01, 2010

I have two conceptual entities:  Employee and Mailbox.

Employee is associated with 0,1..n Mailboxes.

There are two associative roles "owner" and "reader". 

In the underlying SQL database, there is a link table called MailboxView that links theEmployee and Mailbox tables and has an intersection data column of "Role".

In the EF entity model, this link table is represented as data entity because there is an intersection  data column  - hence 3 EF entities:

Employee --> MailboxView <-- Mailbox

The relevant use-cases are:

1.  An Employee can read and change  Mailboxes for which their Role="owner"

2. An Employee has read-only access to Mailboxes for which their Role="reader"

Can anyone suggest the simplest pattern of business objects which implement this behaviour?

Can I, for example, have two collection objects - OwnerMailboxes, which is an ECC and ReaderMailboxes which is a ROC - both having Mailbox as items?  I could use join queries on the entity model (per Julia Lehrman's article at: http://learnentityframework.com/LearnEntityFramework/tutorials/many-to-many-relationships-in-the-entity-data-model/

Is there a better pattern?



JoeFallon1 replied on Wednesday, March 03, 2010

I vote against your plan to use the Mailbox child class in both the ECC and the ROC. Rocky has stated many times that the fact that two objects have many of the same properties is not a good enough reason to try to "re-use code". I agree.

I agree that an Employee object should have two collections as you named them. And that they should be an ECC and an ROC.

The ECC should have an editable child BO named Mailbox.

But the ROC should have an internal class named MailboxInfo which has Public Get and Friend Set methods for each Property. It should also have 2 constructors:

     Private Sub New()
        'require use of factory methods
      End Sub

      Friend Sub New(ByVal dr As SafeDataReader)
        With dr
          mCode = Trim(.GetString("code"))
        End With
      End Sub

The Friend constructor is used by the ROC to populate each instance of the Info class.

     RaiseListChangedEvents = False
      IsReadOnly = False

      Dim dr As SafeDataReader = Nothing
      Dim strSQL As String = "someSQL"

          dr = New SafeDataReader(DAL.ExecuteReader(strSQL))

          While dr.Read
            Dim info As New someInfo(dr)
          End While

        Catch ex As Exception
          Throw New ApplicationException("Exception in myList DataPortal_Fetch.", ex)
          If dr IsNot Nothing Then dr.Close()
          IsReadOnly = True
          RaiseListChangedEvents = True
        End Try



ajj3085 replied on Wednesday, March 03, 2010

Normally I'd agree, but in this case it seems like a case where you're opening a detail screen to which you only have readonly access.  For example, in my system a user might be able to view everything about an Order, but never be able to edit it.  I don't see a reason to create an identical screen, with an identical (but readonly) BO just to display the data. 

The MailBox class could have an OwnerId property, and its only a few lines of business code which determines access, readonly or read / write.

RockfordLhotka replied on Wednesday, March 03, 2010

If this is the same screen, and same object, with different authorization based on the user and object state, then it seems like the solution is to use the authorization subsystem?

Override CanWriteProperty() and return false if the user isn't authorized to manipulate the object? And override Save() to throw an exception if they try to save?

ajj3085 replied on Wednesday, March 03, 2010

Is this question directed at me, or the OP?

FrazerS replied on Wednesday, March 03, 2010

Thanks to all who provided feedback on this one.

I think that approaching this as an authorization issue will work best for me.  My OP failed to point out that Mailbox have Folders, Folders have Folders, Folders have Messages etc. etc.  I need to provide a view of the entire structure that differs only in accessibility, based on the relationship between the Employee and a particular Mailbox.  While I need to prototype this a bit further and see, for example, how CanWriteProperty is (or isn't) propagated to child objects, it seems more promising to take the tack suggested by Rocky.

Thanks again,



Copyright (c) Marimer LLC