使用动态唯一键值对linq / lambda表达式列表过滤数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用动态唯一键值对linq / lambda表达式列表过滤数据相关的知识,希望对你有一定的参考价值。

我有一张如下表

id  speciesid   value
--------------------------------
1   1       ABC
1   2       EDF
2   2       XYZ
3   1       PQR

从上表中我需要根据唯一的对来过滤数据

例如:

说独特的对是像{{1,ABC},{2,EDF}}在对数据中关键是物种,价值是表中的值

所以预期的结果是

id  speciesid   value
--------------------------------
1   1       ABC
2   2       EDF

输入数据也是动态的键值对,因此一次可以有两个或三个或n个对。

我在堆栈溢出中看到this帖子

但它处理的是常量数据对及其纯SQL查询。

注意:我脑海中的一个解决方法就是创建一个列表并循环遍历对,并将结果添加到列表中。

另一个可能是我们可以使用linq中的contains

可以是其他选项o编写接受键值对的函数并返回相应的结果

但我相信会有一个简单/正确的方法来做同样的事情。

任何帮助将不胜感激。

编辑(上面的场景是我在下面的实例中包含的一个示例):

 public SearchBase<Species> GetAdvancedSearchSpeciesList(SpeciesAdvancedSearchRequest request)
    {
        var ids = request.SpeciesAdvancedSearch.Select(o => o.FieldId).ToList();
        SearchBase<Species> searchResult = new SearchBase<Species>();
        List<Species> species = new List<Species>();
        var speciesList = _dbContext.Species.Join(_dbContext.SpeciesDetails,
           sp => sp.Id, sd => sd.SpeciesId, (sp, sd) => new { sp, sd })
           .Join(_dbContext.SpeciesFields, mapper => mapper.sd.SpeciesFieldId, sf => sf.Id, (mapper, sf) => new { mapper, sf })
           .Where(o =>
             ids.Contains(o.sf.Id)
           ).ToList();
        species = speciesList.Select(it => new Species()
        {
            CommonName = _resourceProvider.IsEnglish() ? it.mapper.sp.CommonNameEn : it.mapper.sp.CommonNameAr,
            ProfileImage = it.mapper.sp.ProfileImage,
            ScientificName = _resourceProvider.IsEnglish() ? it.mapper.sp.ScientificNameEn : it.mapper.sp.ScientificNameAr,
            SpeciesCategoryId = it.mapper.sp.SpeciesCategoryId,
            EcosystemTypeId = it.mapper.sp.EcosystemTypeId,
            Id = it.mapper.sp.Id,
            IUCNStatusId = it.mapper.sp.IUCNStatusId,
            LocalStatusId = it.mapper.sp.LocalStatusId
        }).ToList();
        var result = species.Where(sp => request.SpeciesAdvancedSearch.Contains(new SpeciesAdvancedSearch()
        {
           FieldId=sp.Id
        }));
// here the result count is 0
        int totalCount = speciesList.Count();
        request.Size = request.Size == 0 ? totalCount : request.Size;
        searchResult.Total = totalCount;
        searchResult.PageNumber = request.PageIndex;
        searchResult.AddRange(species.Skip((request.PageIndex - 1) * request.Size).Take(request.Size).ToList());
        searchResult.TotalItemsInPage = searchResult.Count;
        return searchResult;
    }

public class SpeciesAdvancedSearchFieldRequest
{
    public int MasterSpeciesCategoryId { get; set; }

    public int EcoSystemTypeId { get; set; }
}

2级

public class SpeciesAdvancedSearchRequest:PaginationRequest
{
    public ICollection<SpeciesAdvancedSearch> SpeciesAdvancedSearch { get; set; }

}

这就是我正在使用的代码。

答案

唉,你忘了给表和参数命名。如果我谈到“你的输入表”和“你的输入参数”,那将是相当困难的,所以让我们定义它们:

class Animal
{
    public int Id {get; set;}
    public int SpeciesId {get; set;}
    public string Value {get; set;}   // I haven't got a clue what value "2" would mean
}

class QueryParam
{
    public int SpeciesId {get; set;}
    public string Value {get; set;}
}

显然你有一系列的Animals,存储在你称之为table的东西中。你再次忘了提到桌子的类型。我认为它是DBMS中的一个表,可以通过实体框架使用SQL进行访问。可能是DbSet<Animal>。所以我想你有以下输入:

IQueryable<Animal> animals = myDbContext.Animals;
IEnumerable<QueryParam> inputParameters = new QueryParam[]
{
    new QueryParam() {SpeciesId = 1, Value = cow},
    new QueryParam() {SpeciesId = 2, Value = cat},
};

现在你想要所有具有SpeciesId / Value组合的动物至少等于inputParameters的一个元素。

TODO:如果存在多个具有SpeciesId == 1和Value ==“cow”TODO的行,则定义您想要的内容:指定区分大小写。

var result = animals.Where(animal => inputParameters.Contains(new QueryParam()
    {
          SpeciesId = animal.SpeciesId,
          Value = animal.Value,
    }));

以上是关于使用动态唯一键值对linq / lambda表达式列表过滤数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用linq从字典中获取嵌套键值对[重复]

Lambda表达式中 select 怎么动态添加查询字段

如何为CriteriaOperator过滤对象转换为lambda表达式,即:linq to xpo的动态where语句

LINQ TO SQL

Linq Where() lambda 表达式中的“或”等价物

具有嵌套属性的动态 linq 表达式树