EF Core 5 在多列中使用 Contains

16 浏览
0 Comments

EF Core 5 在多列中使用 Contains

我有两个模型,大致如下:

public class Filter
{
    public string Key {get;set;}
    public Guid ProgramId {get;set;}
}
public class MyEntity
{
    public string Name {get;set;}
    public string Key {get;set;}
    public Guid ProgramId {get;set;}
}

我想获取所有MyEntity,其中KeyProgramId至少在列表中出现一次。由于KeyProgramId都可以存在于不同的Filter中的不同组合中,所以KeyProgramId的组合至关重要。因此,KeyProgramId必须匹配。

我的代码大致如下:

// 初始化过滤器的方式显然不同,但可能如下所示
var filters = new []
{
    new Filter { Key = "1", ProgramId = Guid.NewGuid() },
    new Filter { Key = "2", ProgramId = Guid.NewGuid() }
}

我尝试了以下几种方法。如果它们在内存中评估,所有示例都能给出我想要的结果,但是没有一种可以执行/转换为SQL。

备选方案1. 基于这个问题

var concatFilters = filters.Select(x => x.Key + "_" + x.ProgramId).ToArray();
var result = myContext.MyTable.Where(x => concatFilters.Contains(x.Key + "_" +  x.ProgramId));
// 它报错:将表达式转换为数据类型nvarchar时出现算术溢出错误。

备选方案2:

var filterPrograms = filters.Select(x => new { Key = x.Key, ProgramId = x.ProgramId }).ToArray();  
var query = myContext.MyTable.Where(x => filterPrograms.Contains( new { Key = x.Key, ProgramId = x.ProgramId} ));
// 它无法转换。

备选方案3:

var query = myContext.MyTable.Where(x => filters.Any(y => y.Key == x.Key && y.ProgramId == x.ProgramId));
// 它无法转换。

我使用分页,并且需要将其在SQL中评估以使我的分页正常工作。我正在使用带有EF Core 5.0.6的.NET 5。有什么想法吗?

0
0 Comments

EF Core 5 Contains with several columns出现的原因是需要在EF Core 5中使用Contains方法来进行多列筛选,但是默认情况下EF Core 5不支持在Contains中使用多列。为了解决这个问题,可以使用扩展方法FilterByItems来实现多列筛选。

解决方法如下:

1. 首先,需要创建一个Filter类,该类包含需要筛选的列,比如Key和ProgramId。

2. 然后,使用Filter类的实例数组来存储需要筛选的条件,如下所示:

var filters = new []
{
    new Filter { Key = "1", ProgramId = Guid.NewGuid() },
    new Filter { Key = "2", ProgramId = Guid.NewGuid() }
};

3. 最后,使用FilterByItems方法来进行筛选,该方法接受一个Lambda表达式作为参数,用于指定筛选条件。在Lambda表达式中,可以使用x表示当前查询的实体,f表示Filter类的实例。在这个例子中,使用了x.Key == f.Key && x.ProgramId == f.ProgramId这个条件进行筛选。最后一个参数指定是否进行精确匹配。

完整的代码如下:

var result = myContext.MyTable
    .FilterByItems(filters, (x, f) => x.Key == f.Key && x.ProgramId == f.ProgramId, true);

通过以上方法,可以在EF Core 5中使用Contains方法进行多列筛选。这个方法不仅效果很好,而且生成的SQL语句也很优雅。感谢这个解决方法的提供者。

0