Beispiel #1
0
        protected Type ThenInclude(Type sourceType, string include)
        {
            if (sourceType == typeof(HealthFacility))
            {
                Queryable = HealthFacilityIncludeMapper.ThenInclude(Queryable, include, this);
                return(HealthFacilityIncludeMapper.GetRelationshipType(include));
            }

            if (sourceType == typeof(Practitioner))
            {
                Queryable = PractitionerIncludeMapper.ThenInclude(Queryable, include, this);
                return(PractitionerIncludeMapper.GetRelationshipType(include));
            }

            if (sourceType == typeof(Practice))
            {
                Queryable = PracticeIncludeMapper.ThenInclude(Queryable, include, this);
                return(PracticeIncludeMapper.GetRelationshipType(include));
            }

            return(null);
        }
Beispiel #2
0
        public async Task Run()
        {
            #region Fetching

            using var querySession = _store.QuerySession(WunshcInc);

            #region Get single Document

            var stopwatch = new Stopwatch();
            stopwatch.Start();

            var singleDocument = await querySession.Query <HealthFacility>()
                                 .SingleAsync(x => x.Id == HealthFacilityId);

            stopwatch.Stop();

            Log.Information($"Single document id: {singleDocument.Id}, - {stopwatch.Elapsed.ToString()}");

            #endregion

            #region Fetch multiple documents with paging

            stopwatch.Restart();

            var multipleDocuments = await querySession.Query <HealthFacility>()
                                    .ToPagedListAsync(1, 20);

            Log.Information(
                $"Multiple document with paging count, total count: {multipleDocuments.Count} - {multipleDocuments.TotalItemCount} - {stopwatch.Elapsed}");

            #endregion

            #region Fetch multiple documents with 2 level includes

            stopwatch.Restart();

            var practiceDict     = new Dictionary <string, Practice>();
            var practitionerDict = new Dictionary <string, Practitioner>();
            var fetched          = await querySession.Query <HealthFacility>()
                                   .IncludeInverted(x => x.HealthFacility, practiceDict)
                                   .ThenInclude <Practice, Practitioner, string>(x => x.Practitioner, practitionerDict)
                                   // We have no other choice than to write where statement targeting dynamic values using raw SQL.
                                   // This could be abstracted into some compiled queries to facilitate the query process.
                                   // We should probably need to restrict the amount of possible filters to specific attributes if we don't want to build a fully dynamic query builder for our MVP
                                   .Where(x => x.MatchesSql("d.data -> 'Values' ->> 'Name' ILIKE ?", "%Braun%"))
                                   .ToListAsync();

            Log.Information(
                $"Multiple document with 2 level include count, included practitioner count, included practices count, elapsed time: {fetched.Count} - {practitionerDict.Count} - {practiceDict.Count} - {stopwatch.Elapsed.ToString()}");

            #endregion

            #region Fetch multiple documents with 3 level includes with paging

            stopwatch.Restart();

            var healthFacilityDict = new Dictionary <string, HealthFacility>();
            practiceDict     = new Dictionary <string, Practice>();
            practitionerDict = new Dictionary <string, Practitioner>();
            var healthServices = await querySession.Query <HealthService>()
                                 .Include(x => x.HealthFacilityId, healthFacilityDict)
                                 .ThenIncludeInverted <HealthFacility, Practice, string>(x => x.HealthFacility, practiceDict)
                                 .ThenInclude <Practice, Practitioner, string>(x => x.Practitioner, practitionerDict)
                                 .Where(x => x.EqualsString(new [] { "SpecialityId" }, SpecialityId))
                                 .Take(10)
                                 .ToListAsync();

            stopwatch.Stop();

            Log.Information(
                $"Multiple document with paging and 3 level include count, included health facilities, included practitioners count, included practices count, elapsed time: {healthServices.Count} - {healthFacilityDict.Count} - {practitionerDict.Count} - {practiceDict.Count} - {stopwatch.Elapsed.ToString()}");

            #endregion

            #region Fetch multiple documents with 3 level includes with compiled query

            stopwatch.Restart();

            healthFacilityDict = new Dictionary <string, HealthFacility>();
            practiceDict       = new Dictionary <string, Practice>();
            practitionerDict   = new Dictionary <string, Practitioner>();
            healthServices     = await querySession.Query <HealthService>()
                                 .Include(x => x.HealthFacilityId, healthFacilityDict)
                                 .ThenIncludeInverted <HealthFacility, Practice, string>(x => x.HealthFacility, practiceDict)
                                 .ThenInclude <Practice, Practitioner, string>(x => x.Practitioner, practitionerDict)
                                 .Where(x => x.HasSpeciality(SpecialityId))
                                 .ToListAsync();

            stopwatch.Stop();

            Log.Information(
                $"Multiple document and 3 level include count, included health facilities, included practitioners count, included practices count, elapsed time: {healthServices.Count} - {healthFacilityDict.Count} - {practitionerDict.Count} - {practiceDict.Count} - {stopwatch.Elapsed.ToString()}");

            #endregion

            #region Fetch multiple documents with include mappers

            stopwatch.Restart();

            var healthFacilityQuery = querySession.Query <HealthFacility>();
            var includeMapper       = new HealthFacilityIncludeMapper(healthFacilityQuery);
            var healthFacilities    = await includeMapper
                                      .Include(new [] { "practices.practitioner", "healthServices" })
                                      .Take(20)
                                      .ToListAsync();

            stopwatch.Stop();

            Log.Information(
                $"Multiple document with include mapper, included practices count, included practitioners count, included healthServices count, elapsed time: {healthFacilities.Count} - {includeMapper.Practices.Count} - {includeMapper.Practitioners.Count} - {includeMapper.HealthServices.Count} - {stopwatch.Elapsed.ToString()}");

            #endregion

            #endregion

            #region Creating, updating, deleting

            Log.Information("Creating/Updating/Deleting resources");

            using var createSession = _store.LightweightSession(WunshcInc);

            var healthFacilityId = await CreateHealthFacility(createSession);

            Log.Information($"Created health facility with id: {healthFacilityId}");

            var practitionerId = await CreatePractitioner(createSession);

            Log.Information($"Created practitioner with id: {practitionerId}");

            var practiceId = await CreatePractice(createSession, healthFacilityId, practitionerId);

            Log.Information($"Created practice with id: {practiceId}");

            practiceDict     = new Dictionary <string, Practice>();
            practitionerDict = new Dictionary <string, Practitioner>();
            var newlyCreatedHealthFacility = await createSession.Query <HealthFacility>()
                                             .IncludeInverted(x => x.HealthFacility, practiceDict)
                                             .ThenInclude <Practice, Practitioner, string>(x => x.Practitioner, practitionerDict)
                                             .SingleAsync(x => x.Id == healthFacilityId);

            Log.Information($"Fetched health facility with practices + practitioners: {newlyCreatedHealthFacility.Id} - {practiceDict.FirstOrDefault().Value.Id} - {practitionerDict.FirstOrDefault().Value.Id}");

            await UpdateHealthFacility(createSession, healthFacilityId);

            var updatedHealthFacility = await createSession.LoadAsync <HealthFacility>(healthFacilityId);

            Log.Information($"New bathroom count + emails: {updatedHealthFacility.Values["BathroomCount"]} - {(updatedHealthFacility.Values["Emails"] as dynamic[]).First().Value}");

            createSession.Delete <Practice>(practiceId);
            await createSession.SaveChangesAsync();

            var independentHealthFacility = await createSession.LoadAsync <HealthFacility>(healthFacilityId);

            var independentPractitioner = await createSession.LoadAsync <Practitioner>(practitionerId);

            Log.Information($"Deleting practice does not cascade to HealthFacility or Practitioner: {independentPractitioner != null && independentHealthFacility != null}");

            practiceId = await CreatePractice(createSession, healthFacilityId, practitionerId);

            createSession.Delete <Practitioner>(practitionerId);
            await createSession.SaveChangesAsync();

            var practice = await createSession.LoadAsync <Practice>(practiceId);

            Log.Information($"Deleting practitioner cascade delete to practice: {practice == null}");

            #endregion
        }