Linq搜索数据库考虑重复项

时间:2018-11-19 12:59:09

标签: database linq any

我遇到了通过重复的列表值搜索数据库的问题。

首先,我通过给定的字符串搜索所有匹配项。

var parentIdList =  await _context.ECATEGORIES
            .Where(a => a.NAME.ToLower().Contains(partOfName.ToLower()))
            .ToListAsync(ct);

然后

当parentIdList的给定PARENTID等于数据库ID时,我检索所有名称

 var mainName = await _context.ECATEGORIES
                .Where(a=> parentIdList.Any(p=>p.PARENTID==a.ID) )
                .Select(s => s.NAME)
                .ToListAsync(ct);

我的问题是,有时属性PARENTID是重复的。

例如PARENTID = {1,1,2,2,4,5,6}

那么结果是mainName = {“ a”,“ b”,“ c”,“ d”,“ e”}

但是我要mainName = {“ a”,“ a”,“ b”,“ b”,“ c”,“ d”,“ e”}

1 个答案:

答案 0 :(得分:0)

因此,您有一个Categories序列,其中每个Category都有一个Id,一个ParentId和一个Name。您还有一个字符串partOfName

您需要Names中的Categories。全部Categories?否。只有拥有其父项的名称类似于Categories的{​​{1}}(看起来像才能通过使用 contains 在您的代码中)

我不确定您是否使用实体框架。您使用partOfName似乎暗示了这一点。在这种情况下,使用虚拟父代属性会更容易。稍后再见。

如果您不使用实体框架,建议您在一个查询中获取数据:将元素与它们的父级连接,并仅保留父级满足您的_context谓词的联接结果:

contains

现在将每个类别与Category.ParentId = Parent.Id上的validParentIds连接起来

string lowerCasePartOfName = partOfName.ToLower(); // for efficiency: do this only once
IQueryable<Category> categories = myDbContext.Categories;
IQueryable<Category> validParents = myDbContext.Categories
   .Where(category => category.Name.ToLower().Contains(lowerCasePartOfName))

注意,到目前为止,查询已经完成,尚未执行。如果需要,可以将它们串联成一个大的LINQ查询。我不确定这是否会大大提高性能。但是,这会降低可读性。

var query = Categories.Join(validParents, // join categories with validParents
    category => category.ParentId,         // from each category take the ParentId
    parent => parent.Id,                   // from each valid parent take the Id
    (category, parent) => new              // when they match make one new object
    {
        CategoryName = category.Name,
    });

实体框架解决方案

如果您使用实体框架,则您的Category类如下:

var result = query.ToListAsync();

您的查询将更加简单:

  

给我所有类别的名称,其父类别的名称看起来像partOfName

class Category
{
     public int Id {get; set;}
     public string Name {get; set;}

     // every Category has zero or one Parent category:
     public int? ParentId {get; set;}
     public Category Parent {get; set;}

     // every Category has zero or more Children, each of them has this Category as Parent
     public virtual ICollection<Category> Children {get; set;}
}