EF Core 5 在多列中使用 Contains
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
,其中Key
和ProgramId
至少在列表中出现一次。由于Key
和ProgramId
都可以存在于不同的Filter
中的不同组合中,所以Key
和ProgramId
的组合至关重要。因此,Key
和ProgramId
必须匹配。
我的代码大致如下:
// 初始化过滤器的方式显然不同,但可能如下所示 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。有什么想法吗?
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语句也很优雅。感谢这个解决方法的提供者。