我已经为我的通用 repo 实现了一个通用规范模式,但我不知道如何将 a 添加.ThenInclude()
到代码中。
仅供参考 - 我有 3 个实体(User->PracticedStyles->YogaStyles
),当我去取我的时候,User
我想取YogaStyles
他/她的所有练习(例如 bikram、vinyasa 等)。但是我无法获取YogaStyle
实体,我可以获取所有PracticedStyle
实体,User
因为它只有一个实体深,但我不知道如何YogaStyle
从每个实体中获取/包含实体PracticedStyle
。
我正在使用具有通用存储库模式的通用规范模式,并且我创建了一个中间表来保存所有样式,这可能是错误的,或者我不知道如何正确使用通用规范模式?
public class User : IdentityUser<int>
{
public ICollection<PracticedStyle> PracticedStyles { get; set; }
}
public class PracticedStyle : BaseEntity
{
public int UserId { get; set; }
public User User { get; set; }
public int YogaStyleId { get; set; }
public YogaStyle YogaStyle { get; set; }
}
public class YogaStyle : BaseEntity
{
public string Name { get; set; } // strength, vinyasa, bikram, etc
}
这是我的控制器和控制器调用的方法
[HttpGet("{id}", Name = "GetMember")]
public async Task<IActionResult> GetMember(int id)
{
var spec = new MembersWithTypesSpecification(id);
var user = await _membersRepo.GetEntityWithSpec(spec);
if (user == null) return NotFound(new ApiResponse(404));
var userToReturn = _mapper.Map<MemberForDetailDto>(user);
return Ok(userToReturn);
}
public class MembersWithTypesSpecification : BaseSpecification<User>
{
public MembersWithTypesSpecification(int id)
: base(x => x.Id == id)
{
AddInclude(x => x.UserPhotos);
AddInclude(x => x.Experience);
AddInclude(x => x.Membership);
AddInclude(x => x.PracticedStyles);
// doesn't work - yogastyles is not a collection
// AddInclude(x => x.PracticedStyles.YogaStyles);
AddInclude(x => x.InstructedStyles);
}
}
这是来自 BaseSpecification 的“AddInclude”
public class BaseSpecification<T> : ISpecification<T>
{
public BaseSpecification()
{
}
public BaseSpecification(Expression<Func<T, bool>> criteria)
{
Criteria = criteria;
}
public List<Expression<Func<T, object>>> Includes { get; } = new List<Expression<Func<T, object>>>();
protected void AddInclude(Expression<Func<T, object>> includeExpression)
{
Includes.Add(includeExpression);
}
}
这是 getEntityWithSpec
public async Task<T> GetEntityWithSpec(ISpecification<T> spec)
{
return await ApplySpecification(spec).FirstOrDefaultAsync();
}
private IQueryable<T> ApplySpecification(ISpecification<T> spec)
{
return SpecificationEvaluator<T>.GetQuery(_context.Set<T>().AsQueryable(), spec);
}
和规格评估员
public class SpecificationEvaluator<TEntity> where TEntity : class // BaseEntity // when using BaseEntity, we constrain it to on base entities
{
public static IQueryable<TEntity> GetQuery(IQueryable<TEntity> inputQuery, ISpecification<TEntity> spec)
{
var query = inputQuery;
if (spec.Criteria != null)
{
query = query.Where(spec.Criteria); // e => e.YogaEventTypeId == id
}
if (spec.OrderBy != null)
{
query = query.OrderBy(spec.OrderBy);
}
if (spec.OrderByDescending != null)
{
query = query.OrderByDescending(spec.OrderByDescending);
}
if (spec.IsPagingEnabled)
{
query = query.Skip(spec.Skip).Take(spec.Take);
}
query = spec.Includes.Aggregate(query, (current, include) => current.Include(include)); // 'current' represents entity
return query;
}
}