The problem from what I can see is that SSRS violates the Contract Centralisation Pattern. Instead your report should be generated from either the services you have created, or by extending those services. Otherwise you create a tight technology based coupling between your report and your databases, which will make it more difficult to modify, migrate or re-implement your travel and employee systems when the need arrises. The more reports you add this way, the more difficult it will become to change your Travel and Employee implementation.
If you haven't already, I would create reporting operations on the travel service, e.g., if you are using SOAP based services, add a GetTravelRequests
operation, which accepts some sort of querying and pagination parameters, that just returns the TravelID, Travel Request Date, EmployeeID of the matching records. Then create a GetEmployeeTravelRequests
, which composes GetTravelRequests
with a GetEmployeeDetails
operation from the Employee service.
This will be slower that an SSRS based report, but you are free to then change the underlying implementation of the Travel and Employee services, so long as you don't change the service contract.
I've kind-of assumed you are using SOAP, which is what the answer above is based upon, however if RESTful services are an option, then I would recommend the following. Instead of exposing numeric TravelID
s and EmployeeID
s, instead use URIs. For instance, the travel service will create a travel resource for the employee URI in the Travel
database. Then create an Atom based feed of travel requests. You can either stop there and where the report user needs employee details, they can follow the employee URI link. Otherwise, you can use the employee URIs to create a composed Atom feed that includes the employee details for each travel request.
The main advantage of this latter approach is the reduced DB load through the use of HTTP Caching; HTTP GET is the most optimised operation in the world. Your report is now a live report, rather than only as current as when it was last generated, which may be once a day or once a month and if you structure your feed correctly, then the non-head pages never change and can be cached for a year or longer. If you assume that employee details change infrequently, then you can set the max-age to 1 day, in which case a query for a particular employees details will only hit the database once a day.
Finally, another nice benefit, is that it become trivially easy to add a TravelRequests
collection resource to the Employee
resource, which contains an Atom based paginated list of all the travel requests for that employee.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…