【问题标题】:How to filter entities by collection containing two columns?如何按包含两列的集合过滤实体?
【发布时间】:2021-04-19 17:24:08
【问题描述】:

我有一个这样的 SQL Server 表:

Id (int, primary key)
UserId (int)
SomeDate (Date)
JsonData (nvarchar)

在 C# 中,我有一个类似于类型的集合

List<(int UserId, DateTime SomeDate)>

如何从我的 C# 集合中找到与这两个字段匹配的所有数据库条目?我想进行一次数据库调用,而不是迭代列表并一一搜索。

例如,如果 C# 集合有 2 个条目:

(1, '2020-01-02'), (5, '2020-01-01')

我想查找任何匹配的数据库条目。类似的东西(不是真正的代码)

context.DatabaseTable
      .Where(e => (e.UserId == 1 && e.SomeDate == '2020-01-02') ||  
            (e.UserId == 5 && e.SomeDate == '2020-01-01') ||
            ... as many conditions as collection has elements...)

【问题讨论】:

标签: c# entity-framework entity-framework-core .net-5


【解决方案1】:

所以你有一个带有Users 的表,其中每个User 至少有属性IdSomeDate。您还有一系列 {UserId, Date} 组合,并且您想要查询所有 {Id, SomeDate} 的值等于集合中至少一个值的 Users

List<(int UserId, DateTime SomeDate)> collection = ...

var valuesToCompare = colection.Select(element => new
{
    Id = element.UserId,
    Date = element.SomeDate,
});
var users = dbContext.Users.Where(user => valuesToCompare.Contains(new 
    {
        Id = user.Id,
        Date = user.SomeDate,
    }));

我对新的(int UserId, DateTime SomeDate) 类型不是很熟悉。如果可以将 User 转换为新的 (int UserId, DateTime SomeDate),那么您不必执行第一个 Select,Contains 即可。

【讨论】:

  • 仅供参考 C#7 引入了 ValueTuple 类型。您使用的语法是旧的匿名类型语法。
  • Linq 表达式无法与 ValueTuples 一起使用,因为它们需要方法属性来帮助为每个元组值赋予“名称”,而 Linq 表达式不支持。
  • 对我不起作用:“LINQ 表达式 'DbSet() .Where(u => __valuesToCompare_0.Contains(new { Id = u.Id, Date = u.SomeDate }) )' 无法翻译。要么以可翻译的形式重写查询,要么通过插入对“AsEnumerable”、“AsAsyncEnumerable”、“ToList”或“ToListAsync”的调用显式切换到客户端评估。请参阅@987654321 @了解更多信息。”
猜你喜欢
  • 1970-01-01
  • 2017-01-30
  • 1970-01-01
  • 1970-01-01
  • 2016-12-27
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
相关资源
最近更新 更多