Set a Many-to-Many Relationship (EF Core)
- 3 minutes to read
This lesson explains how to create a many-to-many relationship between business objects and how XAF generates the UI for such relationships.
Note
Before you proceed, take a moment to review the previous lesson: Inherit from the Business Class Library Class (EF Core)
Step-by-Step Instructions
Right-click the Business Objects folder in the MySolution.Module project, and choose Add | Class…. Change the file name to Task.cs and click Add. Replace the new file’s content with the following code:
using System.Collections.Generic; using DevExpress.ExpressApp.Model; using DevExpress.Persistent.Base; using DevExpress.Persistent.BaseImpl.EF; namespace MySolution.Module.BusinessObjects { [DefaultClassOptions] [ModelDefault("Caption", "Task")] public class DemoTask : Task { public DemoTask() : base() { TrackedBy = new List<Contact>(); } IList<Contact> trackedBy; public virtual IList<Contact> TrackedBy { get => trackedBy; set => SetReferencePropertyValue(ref trackedBy, value); } } }
Register the DemoTask type and its ancestor in
DbContext
. Edit the BusinessObjects\MySolutionDbContext.cs file as shown below.public class MySolutionDbContext : DbContext { //... public DbSet<DemoTask> Tasks { get; set; } public DbSet<Task> AssignedTasks { get; set; } }
Add the Tasks property in the Contact class implementation.
using System.Collections.Generic; //... public class Contact : Person { public Contact() { Tasks = new List<DemoTask>(); } //... IList<DemoTask> tasks; public virtual IList<DemoTask> Tasks { get => tasks; set => SetReferencePropertyValue(ref tasks, value); } }
Run the application.
In the Contact detail view, the application displays the following elements:
- A list of assigned tasks.
- The New button - allows users to add a new assigned task.
- The Link button - allows users to assign the current contact an existing task.
You can find the same UI in the Tasks detail view.
Detailed Explanation
Add an Association
To add a Many-to-Many association, declare collection properties of both parts of the association as virtual
properties and initialize them in constructors:
public class DemoTask : Task {
public DemoTask() : base() {
TrackedBy = new List<Contact>();
}
IList<Contact> trackedBy;
public virtual IList<Contact> TrackedBy {
get => trackedBy;
set => SetReferencePropertyValue(ref trackedBy, value);
}
}
public class Contact : Person {
public Contact() {
Tasks = new List<DemoTask>();
}
//...
IList<DemoTask> tasks;
public virtual IList<DemoTask> Tasks {
get => tasks;
set => SetReferencePropertyValue(ref tasks, value);
}
}
The code above automatically generates the required intermediate tables and relationships.
Change Application Model in Code
The DemoTask class is decorated with the ModelDefaultAttribute attribute. The attribute parameters specify that the Caption property of the Application Model’s BOModel | DemoTask node is set to “Task”.
You can apply the ModelDefault attribute to a business class or its member to change any property of the Application Model’s BOModel | <Class> or BOModel | <Class> | OwnMembers | <Member> node.
Next Lesson
Set a One-to-Many Relationship (EF Core)