Description:
Could you please provide me with a demo on how to display and edit XPO-based many-to-many relations in the XtraGrid?
Answer:
Applies to:
eXpress Persistent Objects, XtraGrid
Assume we have the following model:
C#using DevExpress.Xpo;
public class User : XPObject {
public User(Session session) : base(session) { }
[Association("Users-Roles")]
public XPCollection<Role> Roles {
get {
return GetCollection<Role>("Roles");
}
}
}
public class Role : XPObject {
public Role(Session session) : base(session) { }
[Association("Users-Roles")]
public XPCollection<User> Users {
get {
return GetCollection<User>("Users");
}
}
}
Visual BasicImports DevExpress.Xpo
Public Class User
Inherits XPObject
Public Sub New(ByVal session As Session)
MyBase.New(session)
End Sub
<Association("Users-Roles")> _
Public ReadOnly Property Roles() As XPCollection(Of Role)
Get
Return GetCollection(Of Role)("Roles")
End Get
End Property
End Class
Public Class Role
Inherits XPObject
Public Sub New(ByVal session As Session)
MyBase.New(session)
End Sub
<Association("Users-Roles")> _
Public ReadOnly Property Users() As XPCollection(Of User)
Get
Return GetCollection(Of User)("Users")
End Get
End Property
End Class
So, lets use two grids to show all the users and roles. We will use them to link the selected user to the selected role. Here is the code to link and unlink User and Role objects:
C#private void LinkUserRole(User user, Role role) {
if(user != null && role != null) {
user.Roles.Add(role); // It's enough to add a link on one side only
//role.Users.Add(user); // XPO adds the second link automatically
}
}
private void UnlinkUserRole(User user, Role role) {
if(user != null && role != null) {
user.Roles.Remove(role); // It's enough to remove a link from one side only
//role.Users.Remove(user); // XPO removes the second link automatically
}
}
Visual BasicPrivate Sub LinkUserRole(ByVal user As User, ByVal role As Role)
If Not user Is Nothing AndAlso Not role Is Nothing Then
user.Roles.Add(role) ' It's enough to add a link on one side only
'role.Users.Add(user) ' XPO adds the second link automatically
End If
End Sub
Private Sub UnlinkUserRole(ByVal user As User, ByVal role As Role)
If Not user Is Nothing AndAlso Not role Is Nothing Then
user.Roles.Remove(role) ' It's enough to remove a link on one side only
'role.Users.Remove(user) ' XPO removes the second link automatically
End If
End Sub
In addition, lets add two more grids: one to show the roles of the selected user and the other to show the users of the selected role. These controls illustrates many-to-many relation management.
And finally lets add Commit and Rollback buttons to illustrate how you can work with UnitOfWork transactions to save or rollback the changes.
C#private void btnCommit_Click(object sender, System.EventArgs e) {
unitOfWork.CommitChanges();
}
private void btnCancel_Click(object sender, System.EventArgs e) {
unitOfWork.ReloadChangedObjects();
if(CurrentUser != null) CurrentUser.Roles.Reload();
if(CurrentRole != null) CurrentRole.Users.Reload();
}
Visual BasicPrivate Sub btnCommit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCommit.Click
unitOfWork.CommitChanges()
End Sub
Private Sub btnCancel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCancel.Click
unitOfWork.ReloadChangedObjects()
If Not CurrentUser Is Nothing Then
CurrentUser.Roles.Reload()
End If
If Not CurrentRole Is Nothing Then
CurrentRole.Users.Reload()
End If
End Sub
See the attachment for the demo application code.
See Also:
How to Implement Many-to-Many Relationships
How to use two XtraGrid controls to display collections of persistent objects with a one-to-many association
How to display and edit persistent objects with a many-to-many association in the ASPxGridView