LINQ - 模拟IN clausule中的多个列

时间:2014-08-29 07:13:16

标签: c# linq entity-framework

在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 [] );

2 个答案:

答案 0 :(得分:0)

更好地理解问题。您希望列匹配的所有行可能会有所帮助:

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>

这家伙正在做类似LINK

的事情
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 });

答案 1 :(得分:0)

有几种方式,都有利有弊,有时候有点棘手......

解决方案1 ​​

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

解决方案2

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

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

你分两步完成,假设你有&#34;没有太多结果&#34;部分匹配(仅在一个字段上)

var field1Collection = joinedCollection.Select(m => m.field1);

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

然后你做完&#34;完成加入&#34;在列举的两个列表中......

解决方案4

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