public static async Task<ProfileDto> GetProfileDto(IDdd ddd, int userId) { var profile = await ddd.GetAsync<Profile>(userId); var user = profile?.User ?? await ddd.GetAsync<IdentityDomain.User>(userId); var dto = new ProfileDto { Username = user.UserName, AddressLine1 = profile?.AddressLine1, AddressLine2 = profile?.AddressLine2, StateFk = profile?.City?.State?.Id ?? 0, CityFk = profile?.City?.Id ?? 0, ZipCode = profile?.ZipCode, Email = user.Email, Telephone = profile?.Telephone, MobilePhone = profile?.MobilePhone }; return dto; }
This code produces City and State list.
The citiesQuery is cached, but it can not produce cache for City entities.
public static async Task<IEnumerable<StateCityDto>> GetListWithStateAsync(IDdd ddd) { var citiesQuery = from c in ddd.Query<City>().FetchOk(fc => fc.State) select new { Id = c.Id, Name = c.Name, StateId = c.State.Id, StateName = c.State.Name }; var citiesList = await citiesQuery.CacheableOk().ToListAsyncOk(); var distinctStates = citiesList.Select(x => new { x.StateId, x.StateName }).Distinct(); var stateCityListDto = from state in distinctStates orderby state.StateName select new StateCityDto { Id = state.StateId, Name = state.StateName, Cities = ( from city in citiesList where city.StateId == state.StateId orderby city.Name select new CityDto { Id = city.Id, Name = city.Name } ).ToList() }; return stateCityListDto.ToList(); }
After saving the Profile:
NHibernate: UPDATE job.profile SET city_fk = :p0 WHERE user_fk = :p1; :p0 = 999 [Type: Int32 (0:0:0)], :p1 = 1 [Type: Int32 (0:0:0)]
When GetProfileDto is called again:
NHibernate: SELECT profile0_.user_fk as user1_1_0_, profile0_.address_line_1 as address2_1_0_, profile0_.address_line_2 as address3_1_0_, profile0_.city_fk as city4_1_0_, profile0_.zip_code as zip5_1_0_, profile0_.telephone as telephone6_1_0_, profile0_.mobile_phone as mobile7_1_0_ FROM job.profile profile0_ WHERE profile0_.user_fk=:p0; :p0 = 1 [Type: Int32 (0:0:0)] NHibernate: SELECT city0_.id as id1_0_0_, city0_.name as name2_0_0_, city0_.state_fk as state3_0_0_ FROM job.city city0_ WHERE city0_.id=:p0; :p0 = 999 [Type: Int32 (0:0:0)]
ProfileDto should get be able to get the City from cached City entities. The SQL log shows otherwise though.
The citiesQuery query in GetListWithStateAsync above, despite the query is cached, that query cannot produce the cache for City entities.
To make GetListWithStateAsync's citiesQuery produce cache for City entities, don't select individual fields of City from the query, to wit:
public static async Task<IEnumerable<StateCityDto>> GetListWithStateAsync(IDdd ddd) { // The citiesQuery is cached. And it also produces cache for City entities. var citiesQuery = ddd.Query<City>().FetchOk(c => c.State); var citiesList = await citiesQuery.CacheableOk().ToListAsyncOk(); var distinctStates = citiesList.Select(x => new { StateId = x.State.Id, StateName = x.State.Name }).Distinct(); var stateCityListDto = from state in distinctStates orderby state.StateName select new StateCityDto { Id = state.StateId, Name = state.StateName, Cities = ( from city in citiesList where city.State.Id == state.StateId orderby city.Name select new CityDto { Id = city.Id, Name = city.Name } ).ToList() }; return stateCityListDto.ToList(); }
After saving the Profile:
NHibernate: UPDATE job.profile SET city_fk = :p0 WHERE user_fk = :p1; :p0 = 992 [Type: Int32 (0:0:0)], :p1 = 1 [Type: Int32 (0:0:0)]
When GetProfileDto is called again:
NHibernate: SELECT profile0_.user_fk as user1_1_0_, profile0_.address_line_1 as address2_1_0_, profile0_.address_line_2 as address3_1_0_, profile0_.city_fk as city4_1_0_, profile0_.zip_code as zip5_1_0_, profile0_.telephone as telephone6_1_0_, profile0_.mobile_phone as mobile7_1_0_ FROM job.profile profile0_ WHERE profile0_.user_fk=:p0; :p0 = 1 [Type: Int32 (0:0:0)]
Without selecting the individual fields of the city in GetListWithStateAsync, the GetProfileDto is now able to get the city from the cached cities produced by cached city query.
Happy coding!
No comments:
Post a Comment