KB Article K18036
Visible to All Users

I want to create a report with two business objects. Does XAF allow this?

Description:
I have two business objects to show in one report:

C#
[DefaultClassOptions] public class DomainObject1 : BaseObject { public DomainObject1(Session session) : base(session) { } private string domainObject1Name; public string DomainObject1Name { get { return domainObject1Name;} set { SetPropertyValue("DomainObject1Name", ref domainObject1Name, value); } } } [DefaultClassOptions] public class DomainObject2 : BaseObject { public DomainObject2(Session session) : base(session) { } private string domainObject2Name; public string DomainObject2Name { get { return domainObject2Name; } set { SetPropertyValue("DomainObject2Name", ref domainObject2Name, value); } } }


Answer:
Currently, XAF allows this only by adding an additional persistent class that will have associations with the necessary persistent classes.
However, we have a suggestion to implement a more advanced way to show a report for several business objects Reports, XAFCore - Temporary classes for hybrid views and reports.
First of all, you need to create a singleton class that will include associations with two necessary persistent classes, and obtain their XPCollection that you wish to show in your report. The second step is to create an object of the Singleton class. To do this, use the UpdateDatabaseAfterUpdateSchema() method of the Updater unit. Now, you will be able to create a report of the Singleton type and show two business objects in one report.
Modified BOs:

C#
[DefaultClassOptions] public class DomainObject1 : BaseObject { public DomainObject1(Session session) : base(session) { } private string domainObject1Name; public string DomainObject1Name { get { return domainObject1Name;} set { SetPropertyValue("DomainObject1Name", ref domainObject1Name, value); } } private Singleton singleObject; [Association("Singleton-DomainObjects1", typeof(DomainObject1))] private Singleton SingleObject { get { return singleObject; } set { SetPropertyValue("SingleObject", ref singleObject, value); } } } [DefaultClassOptions] public class DomainObject2 : BaseObject { public DomainObject2(Session session) : base(session) { } private string domainObject2Name; public string DomainObject2Name { get { return domainObject2Name; } set { SetPropertyValue("DomainObject2Name", ref domainObject2Name, value); } } private Singleton singleObject; [Association("Singleton-DomainObjects2", typeof(DomainObject2))] private Singleton SingleObject { get { return singleObject; } set { SetPropertyValue("SingleObject", ref singleObject, value); } } }
Visual Basic
<DefaultClassOptions()> _ Public Class DomainObject1 Inherits BaseObject Public Sub New(ByVal session As Session) MyBase.New(session) End Sub Private domainObject1Name_Renamed As String Public Property DomainObject1Name() As String Get Return domainObject1Name_Renamed End Get Set(ByVal value As String) SetPropertyValue("DomainObject1Name", domainObject1Name_Renamed, value) End Set End Property Private singleObject_Renamed As Singleton <Association("Singleton-DomainObjects1", GetType(DomainObject1))> _ Private Property SingleObject() As Singleton Get Return singleObject_Renamed End Get Set(ByVal value As Singleton) SetPropertyValue("SingleObject", singleObject_Renamed, value) End Set End Property End Class <DefaultClassOptions()> _ Public Class DomainObject2 Inherits BaseObject Public Sub New(ByVal session As Session) MyBase.New(session) End Sub Private domainObject2Name_Renamed As String Public Property DomainObject2Name() As String Get Return domainObject2Name_Renamed End Get Set(ByVal value As String) SetPropertyValue("DomainObject2Name", domainObject2Name_Renamed, value) End Set End Property Private singleObject_Renamed As Singleton <Association("Singleton-DomainObjects2", GetType(DomainObject2))> _ Private Property SingleObject() As Singleton Get Return singleObject_Renamed End Get Set(ByVal value As Singleton) SetPropertyValue("SingleObject", singleObject_Renamed, value) End Set End Property End Class

The Singleton class must be written in the following manner:

C#
[VisibleInReports(true)] public class Singleton : BaseObject { public Singleton(Session session) : base(session) { } public static Singleton GetInstance(Session session) { Singleton result = session.FindObject<Singleton>(null); if ((object.ReferenceEquals(result, null))) { result = new Singleton(session); result.Save(); } return result; } [Association("Singleton-DomainObjects1",typeof(DomainObject1))] public XPCollection<DomainObject1> DomainObjects1 { get { XPCollection<DomainObject1> coll = new XPCollection<DomainObject1>(Session); return coll; } } [Association("Singleton-DomainObjects2", typeof(DomainObject2))] public XPCollection<DomainObject2> DomainObjects2 { get { XPCollection<DomainObject2> coll = new XPCollection<DomainObject2>(Session); return coll; } } }
Visual Basic
<VisibleInReports(True)> _ Public Class Singleton Inherits BaseObject Public Sub New(ByVal session As Session) MyBase.New(session) End Sub Public Shared Function GetInstance(ByVal session As Session) As Singleton Dim result As Singleton = session.FindObject(Of Singleton)(Nothing) If (Object.ReferenceEquals(result, Nothing)) Then result = New Singleton(session) result.Save() End If Return result End Function <Association("Singleton-DomainObjects1", GetType(DomainObject1))> _ Public ReadOnly Property DomainObjects1() As XPCollection(Of DomainObject1) Get Dim coll As XPCollection(Of DomainObject1) = New XPCollection(Of DomainObject1)(Session) Return coll End Get End Property <Association("Singleton-DomainObjects2", GetType(DomainObject2))> _ Public ReadOnly Property DomainObjects2() As XPCollection(Of DomainObject2) Get Dim coll As XPCollection(Of DomainObject2) = New XPCollection(Of DomainObject2)(Session) Return coll End Get End Property End Class

You need to create an instance of the singleton class in the UpdateDatabaseAfterUpdateSchema method:

C#
public class Updater : ModuleUpdater { public Updater(Session session, Version currentDBVersion) : base(session, currentDBVersion) { } public override void UpdateDatabaseAfterUpdateSchema() { base.UpdateDatabaseAfterUpdateSchema(); Singleton.GetInstance(Session); } }
Visual Basic
Public Class Updater Inherits ModuleUpdater Public Sub New(ByVal session As Session, ByVal currentDBVersion As Version) MyBase.New(session, currentDBVersion) End Sub Public Overrides Sub UpdateDatabaseAfterUpdateSchema() MyBase.UpdateDatabaseAfterUpdateSchema() Singleton.GetInstance(Session) End Sub End Class

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.