LINQ-模拟in子句中的多列

本文关键字:子句 模拟 in LINQ- | 更新日期: 2023-09-27 18:20:01

在oracle中,我可以执行以下查询:

SELECT *
FROM Tabl Tabb
WHERE (tabb.Col1, tabb.Col2) IN ( (1,2), (3,4))

假设我有以下实体:

public class Tabb
{
   public int Col1 {get; set; }
   public int Col2 {get; set; }
   // other props
}

和标准类

public class Search
{
   public int Col1 {get; set; }
   public int Col2 {get; set; }
}

我需要写:

public IEnumerable<Tabb> Select(IEnumerable<Search> s)
{
   var queryable = this.context.Tabbs;
   return queryable.Where('* some *').ToList();
}

如果搜索集合包含具有相同值Col1Col2的搜索实例,我如何选择实体?

编辑

var result = from x in entity
             join y in entity2
             on new { x.field1, x.field2 } equals new { y.field1, y.field2 }

它不起作用(正如我所料)-在可能的情况下,entity2不是实体表,它是静态集合,所以EF抛出异常(比如:找不到要键入Search[]的映射层);

LINQ-模拟in子句中的多列

有几种方法,它们都有优缺点,有时有点棘手。。。

解决方案1

首先枚举ef部分(当然,根据数据的大小,这可能是一个非常糟糕的主意)

解决方案2

您将字段与您确信在字段中找不到的元素(哼)连接起来,并在连接的EF数据上使用Contains。

var joinedCollection =entity2.Select(m => m.field1 + "~" + m.field2);
var result = entity.Where(m => joinedCollection.Contains(m.field1 + "~" + m.field2));

当然,如果field1和field2不是字符串,这会有点复杂,你必须使用类似的东西

SqlFunctions.StringConvert((double)m.field1) + "~" + //etc.

解决方案3

你可以分两步来完成,假设你的部分匹配(只在一个字段上)"不会有太多结果"

var field1Collection = joinedCollection.Select(m => m.field1);
var result = entity.Where(m => joinedCollection.Contains(m.field1)).ToList();

然后对两个枚举列表进行"完全联接"。。。

解决方案4

使用存储过程/生成的原始sql。。。

只是更好地理解了这个问题。你想要列匹配的所有行,这可能会有所帮助:

myDBTable.Where(x => 
     myStaticCollection.Any(y => y.Col2 == x.Col2) && 
     myStaticCollection.Any(y => y.Col1 == x.Col1))
     .ToList()
     .Select(x => new Search { Col1 = x.Col1, Col2 = x.Col2 });

也就是说,我希望静态集合中任何Col2与该数据库Col2匹配的每一行,以及任何Col1与该数据库Col1 匹配的每行

this.context.Searches.Join(
     this.context.Tabbs,
     s => s.Col2,
     t => t.Col2,
     (search, tab) => new {
          search,
          tab
     });

这将返回包含搜索和选项卡的IEnumerable<'a>

这家伙正在做类似的链接

var result = from x in entity
             join y in entity2
             on new { x.field1, x.field2 } equals new { y.field1, y.field2 }

一旦你有了result,你就需要枚举它,以确保你正在访问数据库并取回所有的值。一旦它们在内存中,就可以将它们投影到对象中。

result.ToList().Select(a => new MyEntity { MyProperty = a.Property });