gpt4 book ai didi

asp.net-core-mvc - EF Core 多对多提取查询

转载 作者:行者123 更新时间:2023-12-04 07:27:11 25 4
gpt4 key购买 nike

我有以下多对多关系建模

public class Profile
{
ICollection<Category> Categories { get; set;}
// One-To-Many
ICollection<Platform> Platforms { get; set; }
}

public class Category
{
ICollection<Profile> Profiles { get; set; }
}

public class ProfileCategory
{
public int ProfileId { get; set; }
public Profile Profile { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set;}
}

我正在使用 ASP.NET Core MVC 并有一个过滤器 View 模型,其中对配置文件名称的某些属性进行过滤并且它可以工作。

尝试根据类别进行过滤被证明更难实现(至少解决方案对我来说并不明显:)

从网络上,用户可以选择零个、一个或多个类别进行过滤,因此基本上发送到我的 Controller 的是类别 ID 列表。

IQueryable<Profile> query = _context.Profiles.Include(p => p.Categories).Include(p => p.Platforms);
if(string.IsNullOrEmpty(search.Name))
{
query = query.Where(p => p.Name.IndexOf(search.Name StringComparison.OrdinalIgnoreCase) > 0);
}
if(search.Categories?.Any() != null)
{
query = query.SelectMany(p => p.ProfileCategories)
.Join(search.Categories, pc => pc.CategoryId, cId => cId, (pc,_) => pc.Profile);
}

从这一点来看, Profile 对象是不同的,其他导航属性(例如 Platforms)为空,因此破坏了其他部分。

如何在保留 Profile 对象的原始实例的同时执行连接。我一开始以为它们是一样的,但我错了。

最佳答案

目前,EF Core JOIN 并不完美,我建议进行两个查询:

1) 选择 ProfileId 的列表(基于类别列表):

var profileIds = await _context.ProfileCategory
.Where(x => categoryIds.Contains(x.CategoryId)) // filtering goes here
.Select(x => x.ProfileId)
.Distinct()
.ToListAsync();

2) 根据已知 ID 选择所需数据:
var result = await _context.Profiles
.Include(p => p.Categories).Include(p => p.Platforms)
.Where(x => profileIds.Contains(x.ProfileId))
.ToListAsync();

是的,这是两个查询而不是一个,但是两个简单的查询,使用索引很容易优化。

关于asp.net-core-mvc - EF Core 多对多提取查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40933531/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com