如何在 EF Core 中实现搜索

How to implement search in EF Core

我有一个包含 2 个实体的招聘管理系统应用程序 PersonTag

一个人可以有一个标签列表。

这是我的个人实体:

    public int Id { get; set; }
    public string FirstName { get; set; }
    public string Family { get; set; }
    public long NationalId { get; set; }
    public DateTime BirthDate { get; set; }
    public ICollection<TagAggregate> Tags { get; set; }

这是我的标签实体:

    public int Id { get; set; }
    public string TagName { get; set; }
    public string Description { get; set; }
    public int PersonId { get; set; }
    public PersonAggregate Person { get; set; }

一切正常,除非我想用标签名称搜索人员。

例如,我有一个人 John,有一个 programmer 和一个 designer 标签。

当我搜索这些标签时,它 returns 第一条记录而找不到第二条。

例如,我为 person id 1(即“john”)创建了一个具有值 programmer 的标签名称,然后我为 person id 1(“john”)创建了另一个具有值 designer 的标签名称(再次为 person id 1(“john”))!

它只找到程序员(因为我先创建它)和 returns 204 为“设计师”。

当我删除“programmer”标签时,我可以找到标签名称为“designer”的 john。

不知道是什么问题

这是我的搜索方法:

public async Task<PersonAggregate> FindByTagName(string tagName)
{
    var person = DbSet.Where(p => p.Tags
                                   .Select(t => t.TagName == tagName).FirstOrDefault())
                      .FirstOrDefault();
    return person;
}

您可以使用 LINQ 的 .Any() 扩展方法来实现您的目标。 这是我们的例子:

public static async Task<PersonAggregate> FindByTagName(string tagName)
{
    List<TagAggregate> tags = new List<TagAggregate>() { new TagAggregate() { Id=1 , TagName= "tag1" , Description= "test" , PersonId=1 },
    new TagAggregate() { Id=2 , TagName= "test2" ,Description= "tag2" ,PersonId=1 }};
    List<PersonAggregate> result = new List<PersonAggregate>()
    {
        new PersonAggregate(){ Id = 1, FirstName = "ali" , Family= "ghodsi" ,NationalId=3 ,BirthDate=DateTime.Now ,Tags=tags },
    };
    var person = result
       .Single(p => p.Tags.Any(t => t.TagName == tagName));
    return person;
}

在我的例子中,我创建了一个样本列表来显示我的样本输出,但在你的例子中,你应该像这样改变你的方法:

public async Task<PersonAggregate> FindByTagName(string tagName)
    {
        var person = DbSet
            .Single(p => p.Tags.Any(t => t.TagName == tagName));
        return person;
    }

但我建议您在使用异步方法时最好使用异步 EF Core 方法,例如 ToListAsync()、FirstOrDefaultAsync()、SingleOrDefaultAsync()。 所以我建议你像这样改变你的方法:

public async Task<PersonAggregate> FindByTagName(string tagName)
    {
        return await DbSet
            .SingleOrDefaultAsync(p => p.Tags.Any(t => t.TagName == tagName));
    }

.Any() 扩展方法进入集合并搜索我们期望的条件,如果找到我们的期望值,它 returns 该对象。 您可以在此处阅读有关 .Any() linq 扩展方法的更多信息:Enumerable.Any Method