【发布时间】:2021-08-02 23:39:34
【问题描述】:
我有一个实体模型,它基本上是一个树节点:
[Table("bma_ec_categories")]
public class Category : INotifyPropertyChanged
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("category_id")]
public int CategoryId { get; set; }
[Column("parent_category_id")]
public int? ParentId { get; set; }
[Required]
[Column("category_name")]
[StringLength(50)]
public string Name { get; set; }
public Category Parent { get; set; }
public ICollection<Category> Children { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
在我的 DbContext 中,我有:
modelBuilder.Entity<Category>()
.HasOne(p => p.Parent)
.WithMany(c => c.Children)
.HasForeignKey(k => k.ParentId);
我有一个使用Category的查询:
public async Task<IEnumerable<EcommerceItemDto>> GetAllItemsAsync(User user, string category = "All", int page = 0, int pageSize = 9999)
{
IQueryable<Category> categories;
if (category == "All")
{
categories = _context.Categories
.Include(c => c.Children)
.Include(p => p.Parent)
.AsNoTrackingWithIdentityResolution();
}
else
{
categories = _context.Categories
.Where(n => n.Name == category)
.Include(c => c.Children)
.Include(p => p.Parent)
.AsNoTrackingWithIdentityResolution();
}
var p1 = new SqlParameter("@Custnmbr", SqlDbType.Char, 15) {Value = user.Custnmbr};
var dto = await _context.EcommerceItems
.FromSqlRaw($"SELECT * FROM [cp].[GetEcommerceItemsView] WHERE [CustomerNumber] = @Custnmbr",p1)
.Include(x => x.Category)
.Include(i => i.Images.OrderByDescending(d => d.Default))
.OrderBy(i => i.ItemNumber)
.Where(c => categories.Contains(c.Category) || categories.Any(x => x.Children.Contains(c.Category)))
.Skip(page * pageSize)
.Take(pageSize)
.AsNoTracking()
.ProjectTo<EcommerceItemDto>(_mapper.ConfigurationProvider)
.ToListAsync();
return dto;
}
如果使用默认值“All”调用该方法没有问题,但是如果使用实际的类别名称,我只会得到一个Parent 和直接的Children。我可以做些什么来更改我的查询或我的模型以包含Grand-Children 和Great-Grand-Children 等?
更新
我被要求添加我的EcommerceItemDto 模特:
public class EcommerceItemDto
{
[Key]
public string ItemNumber { get; set; }
public string ItemDescription { get; set; }
[Column(TypeName = "text")]
public string ExtendedDesc { get; set; }
public bool? Featured { get; set; }
public string CategoryName { get; set; }
[Column(TypeName = "numeric(19, 5)")]
public decimal Price { get; set; }
[Column(TypeName = "numeric(19, 5)")]
public decimal QtyOnHand { get; set; }
public ICollection<EcommerceItemImagesDto> Images { get; set; }
}
为了节省空间,我有大约 20 个元数据属性没有包含在内。
【问题讨论】:
-
我知道,在使用 ProjectTo 时,所有包含都将被忽略。也永远不会跟踪查询结果。尝试在没有 Automapper 的情况下编写有效的查询,然后与配置进行斗争。
-
@SvyatoslavDanyliv 很抱歉,恐怕您关于“所有包含都被忽略”的说法不正确。你介意告诉我为什么我的查询不“有效”吗?
-
我知道,因为 ProjectTo 生成自定义投影。当您使用自定义投影时,EF Core 会忽略 Includes。选择整个实体时需要包含。
-
@SvyatoslavDanyliv 查询返回的结果包括图像,并且 sql 服务器上缓存的查询计划中的 sql 正在使用类别进行过滤。我们将不得不同意不同意。
-
您可以在问题中添加
EcommerceItemDto吗?
标签: c# tree entity-framework-core