简体   繁体   English

如何在 EF 中获取与组合列表(键/值)匹配的记录?

[英]How to get records in EF that match a list of combinations (key/values)?

I have a database table with records for each user/year combination.我有一个数据库表,其中包含每个用户/年份组合的记录。

How can I get data from the database using EF and a list of userId/year combinations?如何使用 EF 和 userId/year 组合列表从数据库中获取数据? Sample combinations :示例组合

UserId      Year
1           2015
1           2016 
1           2018
12          2016
12          2019
3           2015
91          1999

I only need the records defined in above combinations.我只需要上述组合中定义的记录。 Can't wrap my head around how to write this using EF/Linq?无法围绕如何使用 EF/Linq 编写此内容?

 List<UserYearCombination> userYears =  GetApprovedYears();

 var records = dbcontext.YearResults.Where(?????);

Classes班级

public class YearResult
{
    public int UserId;
    public int Year;
    public DateTime CreatedOn;
    public int StatusId;
    public double Production;
    public double Area;
    public double Fte;
    public double Revenue;
    public double Diesel;
    public double EmissionsCo2;
    public double EmissionInTonsN;
    public double EmissionInTonsP;
    public double EmissionInTonsA;
        ....
}

public class UserYearCombination
{
    public int UserId;
    public int Year;
}

This is a notorious problem that I discussed before here .这是我之前在这里讨论过的一个臭名昭著的问题。 Krishna Muppalla's solution is among the solutions I came up with there. Krishna Muppalla 的解决方案是我在那里提出的解决方案之一。 Its disadvantage is that it's not sargable, ie it can't benefit from any indexes on the involved database fields.它的缺点是它不是 sargable,即它不能从所涉及的数据库字段上的任何索引中受益。

In the meantime I coined another solution that may be helpful in some circumstances.与此同时,我创造了另一种可能在某些情况下有用的解决方案。 Basically it groups the input data by one of the fields and then finds and unions database data by grouping key and a Contains query of group elements:基本上它按字段之一对输入数据进行分组,然后通过对键和组元素的包含查询进行分组来查找和联合数据库数据:

IQueryable<YearResult> items = null;

foreach (var yearUserIds in userYears.GroupBy(t => t.Year, t => t.UserId))
{
    var userIds = yearUserIds.ToList();
    var grp = dbcontext.YearResults
        .Where(x => x.Year == yearUserIds.Key 
                 && userIds.Contains(x.UserId));
    items = items == null ? grp : items.Concat(grp);
}

I use Concat here because Union will waste time making results distinct and in EF6 Concat will generate SQL with chained UNION statements while Union generates nested UNION statements and the maximum nesting level may be hit.我在这里使用Concat是因为Union会浪费时间使结果不同,并且在 EF6 Concat将生成带有链式UNION语句的 SQL,而Union生成嵌套的UNION语句并且可能会达到最大嵌套级别。

This query may perform well enough when indexes are in place.当索引就位时,此查询可能会执行得足够好。 In theory, the maximum number of UNION s in a SQL statement is unlimited, but the number of items in an IN clause (that Contains translates to) should not exceed a couple of thousands.理论上,SQL 语句中UNION的最大数量是无限的,但IN子句( Contains转换为)中的项目数量不应超过几千个。 That means that the content of your data will determine which grouping field performs better, Year or UserId .这意味着您的数据内容将决定哪个分组字段表现更好, YearUserId The challenge is to minimize the number of UNION s while keeping the number of items in all IN clauses below approx.挑战是最小化UNION的数量,同时将所有IN子句中的项目数量保持在大约以下。 5000. 5000。

you can try this你可以试试这个

//add the possible filters to LIST
var searchIds = new List<string> { "1-2015", "1-2016", "2-2018" };

//use the list to check in Where clause
var result = (from x in YearResults
        where searchIds.Contains(x.UserId.ToString()+'-'+x.Year.ToString())
        select new UserYearCombination
        {
            UserId = x.UserId,
            Year = x.Year
        }).ToList();

Method 2方法二

var d = YearResults
           .Where(x=>searchIds.Contains(x.UserId.ToString() + '-' + x.Year.ToString()))
           .Select(x => new UserYearCombination
                 {
                      UserId = x.UserId,
                      Year = x.Year
                 }).ToList();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 EF从Type获取运行时记录列表 - EF get list of records in runtime from Type 如何在 EF Core 中获取数据库表主键列的列表 - How to get list of database table primary key columns in EF Core 如何在对象列表中获取组合? - How to Get Combinations in a list of objects? 如何根据一对多关系中的知情枚举列表获取记录列表 - EF Core - How to get a list of records based on an informed enumerated list in a 1 to many relationship - EF Core C# &amp; EF:如何获取将复合键与三列进行比较的新记录? - C# & EF : how to get the new records comparing compound key with three columns? 如何从第二个表中获取多个记录基于第一个表中的记录列表使用EF - How to get multiple Records from Second table base on list of record from First table Using EF 我想在清单EF中获取值 - I want to get values in List EF 如何有效地获得对象列表的唯一组合 - How to efficiently get unique combinations of a list of objects EF 5 - 传递的主键值的数量必须与实体上定义的主键值的数量相匹配 - EF 5 - The number of primary key values passed must match the number of primary key values defined on the entity 如何在没有包含在EF模型中的外键的情况下从一个表到多个表列中获取值 - How to get values from a one to many table column without foreign key included in EF model
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM