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