Configure a One-to-Many Relationship
- 5 minutes to read
This lesson explains how to create a One-to-Many relationship between two entities and how XAF generates the UI for such a relationship.
Note
Before you proceed, take a moment to review the previous lessons:
Employee-Department Relationship
In the MySolution.Module\Business Objects folder, create the
Department
class. Replace the generated class declaration with the following code:using DevExpress.Persistent.Base; using DevExpress.Persistent.BaseImpl.EF; using System.ComponentModel; namespace MySolution.Module.BusinessObjects { [DefaultClassOptions] [DefaultProperty(nameof(Title))] public class Department : BaseObject { public virtual string Title { get; set; } public virtual string Office { get; set; } } }
The code applies the
DefaultProperty
attribute to theDepartment
class. Use this attribute to specify the most descriptive property of your class. Default property values are displayed in the following UI elements:- Detail form captions
- The leftmost column of a List View
- Lookup List Views
Refer to the following topic for more information: Data Annotations in Data Model.
Go to the MySolution.Module\MySolutionDbContext file and add a DbSet of the
Department
class:public class MySolutionEFCoreDbContext : DbContext { //... public DbSet<Department> Departments { get; set; } }
Add the
Department
reference property to theEmployee
class://... public class Employee : BaseObject { //... public virtual Department Department { get; set; } }
When you add a reference property of one entity type to another entity type, you establish the “One” part of the relationship between these entities. In this case it is a relationship between the
Department
andEmployee
entity classes.Note that the property has the
virtual
access modifier for lazy loading implementation. For additional information, refer to the Microsoft documentation: Lazy Loading.Add the
Employees
collection property to theDepartment
class and initialize it in the constructor:// ... using System.Collections.ObjectModel; //... public class Department : BaseObject { //.. public virtual IList<Employee> Employees { get; set; } = new ObservableCollection<Employee>(); }
This way, you implement the “Many” part of the relationship between the
Department
object and theEmployee
object.Add a migration and update the database. See the following section for details: Use a DBMS: Setup Migrations.
Run the application.
Open the Department Detail View. You can see the Employees group. This is how XAF renders the
Employees
collection property.To add objects to the
Employees
collection, use the New or Link button in this tab. The Link button allows users to add references to existingEmployee
objects.- ASP.NET Core Blazor
- Windows Forms
-
To remove a reference to an object from this collection, select this object and click Unlink.
Tip
If you create a new
Department
and then create a newEmployee
in theEmployees
collection, the associatedDepartment
is not immediately visible in the Detail View of the newly createdEmployee
object. The link between these objects is added later when you save theEmployee
object. To change this behavior, use the XafApplication.LinkNewObjectToParentImmediately property. When the property value istrue
, the application creates a link and saves it immediately after you click New.
Open the
Employee
Detail View. In this view, XAF creates a lookup editor for theDepartment
reference property. Lookup editors support incremental filtering. This editor uses a special type of View — Lookup List View. The Lookup List View includes a single column that displays the values of the default property. In your application, these are the values of theTitle
property.- ASP.NET Core Blazor
- Windows Forms
Note
The most common pattern for a relationship is to define properties on both ends of the relationship. At the same time, according to the conventions of Entity Framework Core, it is sufficient to add only the reference property (the “One” part). It establishes the “One-To-Many” relationship between entities and Entity Framework Core automatically creates a foreign key to the related table in the database.
The main difference between these techniques is how XAF renders the application’s UI. When you omit the “Many” part of the relationship, XAF doesn’t create an editor for the omitted collection property in the Detail View of the entity class. You can see an example of this in the following lesson: Implement Reference Properties.
Exercise: Create an Employee-PhoneNumber Relationship
Create a
PhoneNumber
class and implement a One-To-Many relationship between this class and theEmployee
class. This time theEmployee
should be the “One” part of the relationship, while thePhoneNumber
should be the “Many” part. You can find the type declaration in the code sample below.Tip
Remember to register the new entity in
DbContext
and create a new migration for the database.Use the code sample below to replace the autogenerated class declaration in the
PhoneNumber
class:using DevExpress.Persistent.BaseImpl.EF; using System.ComponentModel; namespace MySolution.Module.BusinessObjects; [DefaultProperty(nameof(Number))] public class PhoneNumber : BaseObject { public virtual String Number { get; set; } public virtual String PhoneType { get; set; } public override String ToString() { return Number; } }
This class is not visible in the navigation control.
Run the application. Open the Employee Detail View to see the Phone Numbers group:
- ASP.NET Core Blazor
- Windows Forms
Next Lesson
Configure a Many-to-Many Relationship