如何在 EF Core 中实现搜索

moe*_*our 8 c# asp.net-web-api swagger .net-5

我有一个招聘管理系统应用程序,包含 2 个实体Person& Tag

人可以有一个标签列表。

这是我的个人实体:

    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; }
Run Code Online (Sandbox Code Playgroud)

这是我的标签实体:

    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; }
Run Code Online (Sandbox Code Playgroud)

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

例如,我有一个 person John,带有 aprogrammer和 adesigner标签。

当我搜索这些标签时,它返回第一个记录,但找不到第二个记录。

例如,我使用值程序员为人员 id 1(即“约翰”)创建了一个标签名称,然后我使用值设计师创建了另一个标签名称(再次为人员 id 1(“约翰”))!

它只找到程序员(因为我首先创建了它)并为“设计者”返回 204。

当我删除“程序员”标签时,我可以找到标签名为“设计师”的约翰。

我不知道问题是什么。

这是我的搜索方法:

    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; }
Run Code Online (Sandbox Code Playgroud)

Hoo*_*nHT 8

您可以使用 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;
}
Run Code Online (Sandbox Code Playgroud)

就我而言,我创建了一个示例列表来显示我的示例输出,但在您的情况下,您应该像这样更改您的方法:

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

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

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

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