Saturday, January 05, 2008

We have seen two types of inheritance modeling, at this point I'm interested in modeling an association. This actually turned out to be harder then I had expected, even though the documentation on this subject is good and plentyfull ;-)

However, since you are still reading, I will create a very simple example in the employee class, such that an employee needs to report to another employee.
Remember that employee inherits from person. I was happy to see that I was indeed able to create the relationship!

I've added a new column in the employee table, named: ReportsToID and a foreignkey relation that specifies the primary key base to be Employee/EmployeeID and the foreign key base to be Employee/ReportsToID. In database lingo this simple means that ReportsToID can be filled with an exact EmployeeID and that this relationship is verified (for instance, when deleting an employee, but still having other employees which report to the deleted employee).

 Let's look at the SSDL that I created to match this new foreignkey relationship:

In the EntityContainer section:
          <AssociationSet Name="FK_Employee_Manager"
                          Association="EntityFrameworkTestModel1.Store.FK_Employee_Manager">
            <End Role="Manager" EntitySet="Employee" />
            <End Role="Members" EntitySet="Employee" />
          </AssociationSet>
And the mentioned AssociationSet:
        <Association Name="FK_Employee_Manager">
          <End Role="Manager" Type="EntityFrameworkTestModel1.Store.Employee" Multiplicity="0..1" />
          <End Role="Members" Type="EntityFrameworkTestModel1.Store.Employee" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="Manager">
              <PropertyRef Name="EmployeeID" />
            </Principal>
            <Dependent Role="Members">
              <PropertyRef Name="ReportsToID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>

As you can see, I named the roles: Manager and Members.
The association can be interpreted as follows: An employee (a Member) can have zero or one Manager. A Manager can have zero to infinite Members.

Let's take a look at the C-side of life.
In the EntityContainerSection:
          <AssociationSet Name="TeamMemberToTeamLeader"
                          Association="EntityFrameworkTestModel1.TeamMemberToTeamLeader">
            <End Role="TeamMembers" EntitySet="Person" />
            <End Role="TeamLeader" EntitySet="Person" />
          </AssociationSet>
And the Association is defined as:
        <Association Name="TeamMemberToTeamLeader">
          <End Type="EntityFrameworkTestModel1.Employee" Role="TeamLeader" Multiplicity="0..1" />
          <End Type="EntityFrameworkTestModel1.Employee" Role="TeamMembers" Multiplicity="*" />
        </Association>

I like to use real desciptive names, but this should be easy enough to follow.

Also, I added navigationProperties to my model, so I can easily follow an association:
        <EntityType Name="Employee" BaseType="EntityFrameworkTestModel1.Person">
          <NavigationProperty Name="TeamLeader" Relationship="EntityFrameworkTestModel1.TeamMemberToTeamLeader" FromRole="TeamMembers" ToRole="TeamLeader" />
          <NavigationProperty Name="TeamMembers" Relationship="EntityFrameworkTestModel1.TeamMemberToTeamLeader" FromRole="TeamLeader" ToRole="TeamMembers" />
        </EntityType>

Remember that an association is an independent entity, it only defines a relation that can be traversed. We need Navigationproperties to actually use the association. This way it can be shared between models.

The actual mapping between the store and the conceptual model is interesting:
          <AssociationSetMapping Name="TeamMemberToTeamLeader"
                                 TypeName="EntityFrameworkTestModel1.TeamMemberToTeamLeader"
                                 StoreEntitySet="Employee" >
            <EndProperty Name="TeamMembers">
              <ScalarProperty Name="PersonID" ColumnName="EmployeeID" />
            </EndProperty>
            <EndProperty Name="TeamLeader">
              <ScalarProperty Name="PersonID" ColumnName="ReportsToID" />
            </EndProperty>
            <Condition ColumnName="ReportsToID" IsNull="false" />
          </AssociationSetMapping>

Here you can see that I am mapping the ScalarProperty PersonID instead of EmployeeID; remember we are using inheritance here.

The condition is needed to solve some errors I was having. I think it can be read as: the association only works if there is a reportsID value set.

Some test code:

Employee e = new Employee();
e.Firstname = "Ian";
e.Lastname = "Mort";
context.AddToPerson(e);

Einstein smartNerd = new Einstein();
smartNerd.Firstname = "Albert";
smartNerd.Lastname = "Einstein";
smartNerd.Language = "C# 3.5";
smartNerd.TeamLeader = e;
context.AddToPerson(smartNerd);

Elvis elvis = new Elvis();
elvis.Firstname = "Elvis";
elvis.Lastname = "Presley";
elvis.Language = "C# 2.0";
elvis.TeamLeader = e;
context.AddToPerson(elvis);

At this point I can check that e.TeamMembers has a count of 2 and both employees have a teammember property! So, everything working as expected.

Reading back this post, I can see it was actually pretty simple. However, the syntax seems to be overly complex and a small mistake leads to weird errors!

 

Thursday, December 02, 2010 8:24:54 AM (Romance Standard Time, UTC+01:00)
xiaolaba Only after before a "concept, unlike other principles vile ugg boots on sale and difficult to understand, on the contrary boots uggs on sale, it is simple and easily arouses the child's confidence and high spirits, goals are small but specific ugg boot sale. In this goal, the child without understanding thoughts, solid, conscientious to do with bailey button, abandoned children in a meeting in surface. Small success to classic mini uggs, and gets the others recognized and appreciated, will gradually moving towards greater success mini uggs on sale, you'll make a big career. Words can ruin a man's confidence uggs mini on sale, even burst of his hopes of survival classic mini uggs on sale, But a word can also encourage one from loss to come out, or make one from a new Angle know yourself ugg classic cardy, changed his life. So at any time, we don't save said an encouraging word, give a trusting eyes ugg classic short, do a duck-yard trifle. A person's strength for himself perhaps is very limited ugg classic short navy, but he has probably help stimulate another person's infinite potential ugg boot sale.
Comments are closed.